vue2与vue3的区别
- 双向数据绑定原理不同。
- vue2使用 Object.defineProperty() API实现双向数据绑定。当属性被访问或修改时,会触发相应的 getter 和 setter 函数,从而实现对数据的观察和响应。
-
// vue2实现双向数据绑定的示例代码 const vm = new Vue({ data: { count: 0 }, watch: { count(newVal, oldVal) { console.log('count changed from', oldVal, 'to', newVal); } } }); vm.count++; // 访问count属性,触发watch中的count函数 vm.count = 10; // 修改count属性,触发watch中的count函数
- vue3使用 Proxy API实现双向数据绑定。通过创建一个代理对象,并设置其 handler 来拦截对数据的访问和修改操作,从而实现对数据的观察和响应。
-
// vue3实现双向数据绑定的示例代码 const vm = new Vue({ data: { count: 0 } }); const proxy = new Proxy(vm, { get(target, key) { console.log(`getting ${key}`); return target[key]; }, set(target, key, value) { console.log(`setting ${key} to ${value}`); target[key] = value; return true; // 必须返回true,表示数据已发生改变 } }); proxy.count++; // 访问count属性,触发handler中的get函数 proxy.count = 10; // 修改count属性,触发handler中的set函数
- 生命周期钩子。
- vue2有多个生命周期钩子,包括created、mounted、updated、destroyed等。这些钩子可以在组件的不同生命周期阶段执行相应的操作。
- vue3引入了组合API,通过Composition API可以将多个钩子函数组合成一个composition function。这样可以更好地组织和管理代码。另外,vue3还新增了一些钩子函数,如onMounted、onUpdated等。
- 组件通信。
- vue2使用 v-model 进行父子组件双向数据绑定,也可以使用 emit 和 on 方法进行子组件向父组件传递消息。
-
// 子组件 this.$emit('input', value); // 父组件 this.$refs.childComponent.$on('input', handleInput);
- vue3使用 emit 进行子组件向父组件传递消息,使用 wire 进行父组件向子组件传递数据。另外,vue3还新增了全局的 provide 和 inject 函数,可以通过这两个函数实现跨组件共享数据。
-
// 子组件 emit('input', value); // 父组件 wire.childComponent.on('input', handleInput);
- 异步操作。
- vue2使用 Promise 或 http 来处理异步请求,但需要手动调用 then 或 http 来处理异步请求,但需要手动调用 then 或 http.then 来处理异步结果。
-
// vue2的异步请求示例代码 axios.get('/api/data').then(response => { this.data = response.data; });
- vue3引入了 async combinator,可以将异步操作的结果缓存起来,避免了重复请求。另外,vue3还新增了 ref 和 reactive 来更好地处理响应式数据。
-
// vue3的异步请求示例代码 import { ref, reactive } from 'vue'; import { getData } from './api'; const data = ref(null); const loading = ref(false); const fetchData = async () => { loading.value = true; // 开始加载数据,更新loading状态为true const response = await getData(); // 异步请求数据 data.value = response.data; // 更新data为响应数据,触发视图更新 loading.value = false; // 数据加载完毕,更新loading状态为false,触发视图更新 };
- 路由。
- vue2使用 vue-router 进行路由管理,需要在每个路由组件上手动添加 meta 字段来描述该路由的详细信息。
-
const routes = [ { path: '/', component: Home, meta: { title: 'Home' } }, { path: '/about', component: About, meta: { title: 'About' } }
] - vue3使用 vue-router 4.x 版本,新增了 router.addRoutes 方法,可以通过该方法动态添加路由。另外,vue-router 4.x 还新增了导航守卫功能,可以在路由切换时执行一些自定义逻辑。
-
const routes = [ { path: '/', component: Home }, { path: '/about', component: About } ]; router.addRoutes(routes);
- 组件。
- vue2使用 component 标签来定义组件,并通过 is 属性指定组件的名称。另外,vue2还支持混入 (mixin) 和全局混入。
-
<template> <div> <component is="MyComponent"></component> </div> </template> <script> export default { components: { MyComponent: { template: '<div>My Component</div>' } } } </script>
- vue3引入了 Composition API,通过组合API可以将一些低级别的API封装成更高级别的API,使得代码更加易于维护和重用。另外,vue3还支持使用 setup 函数来提取组件的逻辑代码,使得组件的定义更加清晰。
- 响应式。
- vue2使用 v-bind 指令和 computed 属性来实现响应式,需要手动绑定数据和更新 DOM。
-
<template> <div> <p>{{ message }}</p> <button @click="changeMessage">Change Message</button> </div> </template> <script> export default { data() { return { message: 'Hello World' }; }, methods: { changeMessage() { this.message = 'Hello Vue'; } } } </script>
- vue3使用 reactive 和 watchEffect 函数来实现响应式,可以自动感知数据变化并更新 DOM。另外,vue3还新增了 watch 和 watchEffect API,可以自定义响应式逻辑。
-
<template> <div> <p>{{ message }}</p> <button @click="changeMessage">Change Message</button> </div> </template> <script> import { reactive } from 'vue'; export default { setup() { const state = reactive({ message: 'Hello World' }); const changeMessage = () => { state.message = 'Hello Vue'; }; return { message: state.message, changeMessage: changeMessage }; } } </script>
- 插件。
- vue2使用 Vue.use() 方法来注册插件,需要在每个插件中手动添加 install 函数。
-
const MyPlugin = { install(Vue, options) { Vue.prototype.$myMethod = function () { console.log('My Method'); }; } }; Vue.use(MyPlugin);
- vue3使用 createApp 方法创建应用,并使用 use 函数来注册插件。另外,vue3还新增了全局API,可以通过全局API调用插件的方法。
-
const app = createApp(App); const MyPlugin = { install(app, options) { app.prototype.$myMethod = function () { console.log('My Method'); }; } }; app.use(MyPlugin);
- 构建。
- vue2使用 vue-cli 脚手架来创建项目,需要安装 node.js 和 npm。另外,vue2还支持 webpack 和 browserify。
-
npm install -g vue-cli vue init webpack my-project
- vue3使用 vue-cli 4.x 版本,新增了 createApp 函数和 createLibrary 函数,可以通过这两个函数创建应用和库。另外,vue3还支持使用 vite 作为构建工具。
-
npm install -g @vue/cli@4 vue create my-project
- 异步组件。
- vue2使用 webpack 的 async 特性来创建异步组件,需要使用 webpack-async-module-polyfill 来确保异步加载模块兼容不同浏览器。
-
const asyncComponent = () => ({ template: '<div>Async Component</div>', resolve(loadModule) { return new Promise((resolve, reject) => { setTimeout(() => { resolve(loadModule('./AsyncComponent.vue')); }, 1000); }); } });
- vue3使用 microtask 和动态 import 语法来创建异步组件,不需要额外引入 polyfill。
-
const asyncComponent = () => import('./AsyncComponent.vue');