Vue2 和 Vue3的区别
Vue2 和 Vue3的区别
Vue是用于创建用户界面的开源JavaScript框架,也是创建单页应用的Web应用框架;用于构建用户界面的渐进式框架,是目前三大主流的框架之一。Vue观众MVC当中的视图层,能更好的获取到组件的数据状态,通过组件内的方法进行视图和模型之间的更新。
Vue2和Vue3de 区别
1、数据监听响应式的区别
Vue2使用Object.defineProperty来实现数据和视图之间的实时更新,通过劫持对象属性的 geter 和 seter,在数据发生变化的时候发出通知
Vue3使用ES6的新特性Porxy来劫持数据,当数据改变时发出通知。消除了Vue2在新对象属性的增加、直接修改数组元素 不会触发响应式机制
Porxy单独为IE浏览器做了适配,解决了Vue在IE不能运行的弊端。
2、项目初始化
Vue2:vue init <模板名称(webpack)> [项目名称]
vue init webpack test
Vue3:vue create [项目名称]
vue create test
3、根节点支持
Vue2仅支持单个根节点
Vue3取消了限制,可支持多个节点共存
4、对TypeScript的支持
vue2:不适合使用ts,vue2是Option API(选项API)风格。options是个简单对象,而ts是一种类型系统、面向对象的语法。
vue3:打造了defineComponent(组合API)函数,使组件在ts下,可以更好的利用参数类型推断
5、创建方法
Vue2
export default {
props: {
title: String
},
data () {
return {
a: '',
b: ''
}
},
methods: {
c() {
}
}
}
Vue3
export default {
props: {
title: String
},
setup () {
const state = reactive({
a: '',
b: ''
})
const c= () => {
}
return {
c,
state
}
}
}
在组合API中,我们需要将生命周期钩子导入到项目中,才能使用
// 组合 API import { onMounted } from 'vue'
6、生命周期
Vue2的周期函数
- beforeCreate
- create
- beforeMount
- mounted
- beforeUpdate
- updated
- beforeDestroy
- destroyed
- errorCaptured
Vue3除了beforeCreate和create方法被setup()代替,Vue3还有如下周期函数
- onBeforeMount ,挂在开始前被调用
- onMonuted,挂载时调用
- onBeforeUpdate,数据更新时调用,适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器
- onUpdated,数据更改导致的虚拟 DOM 重新渲染
- onBeforeUnmounted,卸载组件实例之前调用
- onUnmounted,卸载组件实例后调用
- onActivated,缓存(keep-alive )的组件激活时调用
- onDeactivated, 缓存的组件(keep-alive )停用时调用
- onErrorCaprured
7、文件目录
Vue3中不在包含(webpack.base.conf.js/webpack.dev.conf.js/webpack.prod.conf.js),我们可以在根目录中设置vue.config.js来进行webpack的一些配置
import path from 'path';
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import styleImport from 'vite-plugin-style-import';
import visualizer from 'rollup-plugin-visualizer';
const envConfig = require('./proxy.config');
const NODE_ENV = process.env.NODE_ENV || 'development';
const PORT = process.env.PORT || 10002;
const proxy = process.env.proxy;
const isDev = NODE_ENV === 'development'; // build mode: development
const apiProxy = envConfig.getApiProxy();
const plugins = [
vueJsx({
// options are passed on to @vue/babel-plugin-jsx
}),
styleImport({
libs: [
{
libraryName: 'vant',
esModule: true,
resolveStyle: (name) => {
return `vant/es/${name}/style/index`;
},
},
{
libraryName: 'ant-design-vue',
esModule: true,
resolveStyle: (name) => {
return `ant-design-vue/es/${name}/style/css`;
},
},
],
}),
vue(),
];
if (process.env.NODE_ENV === 'production') {
// 打包依赖展示
plugins.push(
visualizer({
open: true,
gzipSize: true,
brotliSize: true,
})
);
}
const config = {
plugins,
/**
* 在生产中服务时的基本公共路径。
* @default '/'
*/
base: '',
/**
* 与“根”相关的目录,构建输出将放在其中。如果目录存在,它将在构建之前被删除。
* @default 'dist'
*/
outDir: 'assets',
emitManifest: true,
// 引入第三方的配置
optimizeDeps: {
include: ['axios'],
exclude: ['koa2', 'koa-body', 'autoprefixer', 'koa-static-cache', '@vue/server-renderer', 'vue-style-loader'],
esbuildOptions: {
keepNames: false,
},
},
resolve: {
alias: {
// vite中alias必须以斜线开头和结尾,暂时未知原因,这样其实挺不方便的
// 所以在eslint配置alias和文件中导入路径也要相应的修改
'~': path.resolve(__dirname, './src'),
},
},
//这里注意,键名是scss不是sass!一字之差能让你折腾好久
css: {
preprocessorOptions: {
scss: {
// 自动导入全局样式
// globalScss: "@import '~/styles/index.scss';",
javascriptEnabled: true,
},
},
},
define: {
__client__: true,
__dev__: isDev,
__local_proxy__: !!proxy,
},
build: {
// target: 'modules', // browsers with native ES module support.
outDir: `dist`,
assetsDir: '',
emptyOutDir: true,
brotliSize: false, // 禁用 brotli 压缩大小报告
// sourcemap: true,
rollupOptions: {
output: {
manualChunks: {
lodash: ['lodash'],
// vant: ['vant'],
// antd: ['ant-design-vue'],
},
},
},
},
server: {
port: PORT,
cors: true,
// 是否自动在浏览器打开
open: false,
// 是否开启 https
https: false,
// 服务端渲染
ssr: false,
proxy: apiProxy
? {
// 如果是 /api 打头,则访问地址如下
'/api': apiProxy,
'/service': apiProxy,
}
: {},
},
};
export default defineConfig(config);
8、父子传参
Vue2中父组件使用:xxx来向子组件传递参数
<insureinfo-module :form-data="params.policyHolderInfoDto" />
子组件通过props来接受
export default {
props :{
//数据
formData : {
type : Object,
default(){
return {
name : '',
identifyNumber : '',
phone : ''
}
}
},
}
}
Vue3父传子和Vue2传值方式一样 ,Vue3接受参数的方式成为了
//父传子
<OrderItem v-for="item in list" :key="item" :detail="item"
</OrderItem>
子组件通过setup函数接受父组件传递的参数,可以通过toRefs、ref来解构参数,引用方法前需要引入
//子接受,通过setup函数接受
import { reactive, defineComponent, toRefs, onMounted } from 'vue';
import FetchSpanWithColor from '~/modules-pc/components/FetchSpanWithColor.vue';
export default defineComponent({
name: 'OrderItem',
props: {
detail: {
type: Object,
required: true,
},
keyList: {
type: Array
}
},
components: { FetchSpanWithColor },
setup(props, context) {
return { StatusOpts, StatusColorList };
},
});
子传父,事件
Vue2如果监听子组件返回的参数,定义方式是@aa="test"的方式,在父组件中定义test方法,获取子组件传回的数据
//父
<ensure-module @input="getPlanPremium" />
getPlanPremium(val, premium, productCode) {
this.params.premium = premium
this.perPremium = premium
this.$set(this.params, 'productCode', productCode)
if(this.userFormData.insured[0].staffCount != '') {
this.params.premium = premium * this.userFormData.insured[0].staffCount
}
}
子组件
//子组件通过$emit方法通知父组件
this.$emit('input', val, this.planPremium, this.planProductCode);
Vue3中父组件接受和Vue2中的保持一致,子组件回传的方式改变。通过setup函数中的context来触发emit方法,Vue3不在提供this
import { defineComponent, toRefs, computed } from 'vue';
export default defineComponent({
props: {
hideCheck: {
type: Boolean,
default: false,
},
checked: {
type: Boolean,
},
},
emits: ['change'],
setup(props, context) {
context.emit('change', value)
}
)}
持续更新中...
更多推荐
所有评论(0)