目录
1. 性能
2. 组合式 API
3. 生命周期钩子
4. 片段(Fragments)
5. 递归组件
6. 自定义渲染器
7. 全局 API
8. 组件内部的 this
9. 模板语法
10. 兼容性
总结
Vue 2 和 Vue 3 是 Vue.js 框架的两个主要版本,它们在多个方面有所不同。以下是 Vue 2 和 Vue 3 的主要区别:
1. 性能
-
Vue 3:
-
更快的渲染速度:Vue 3 采用了全新的渲染器架构,使用了更高效的算法,使得组件的渲染速度更快。
-
更小的体积:Vue 3 的核心库体积更小,经过压缩和树摇优化后,体积更小,加载速度更快。
-
更好的响应性:Vue 3 使用了 Proxy API 代替 Vue 2 中的
Object.defineProperty
,提供了更全面的响应性支持,包括对数组和对象的动态属性的响应性。
示例:
javascript">// Vue 2 const vm = new Vue({data: {list: [1, 2, 3]} });// 添加一个新元素,需要使用 Vue.set 方法来确保响应性 vm.$set(vm.list, 3, 4);// Vue 3 const { ref } = Vue;const list = ref([1, 2, 3]);// 直接添加一个新元素,自动响应 list.value.push(4);
-
-
Vue 2:
-
渲染速度较慢:使用的是旧的渲染器架构,渲染速度相对较慢。
-
体积较大:核心库体积较大,经过压缩和树摇优化后,体积仍然较大。
-
响应性有限:使用
Object.defineProperty
,对数组和对象的动态属性支持有限。
-
2. 组合式 API
-
Vue 3:
-
组合式 API:引入了新的组合式 API(Composition API),提供了更灵活的代码组织方式,使得逻辑复用和组件维护更加方便。
-
setup 函数:组合式 API 的核心是
setup
函数,它在组件创建之前执行,可以在这个函数中定义响应式数据、计算属性、方法等。
示例:
javascript">// Vue 3 <template><div><p>{{ count }}</p><button @click="increment">Increment</button></div> </template><script> import { ref } from 'vue';export default {setup() {const count = ref(0);const increment = () => {count.value++;};return {count,increment};} }; </script>
-
-
Vue 2:
-
选项式 API:仅支持选项式 API(Options API),通过
data
、methods
、computed
等选项来组织组件的逻辑。 -
逻辑复用困难:选项式 API 在处理复杂组件时,逻辑复用和维护较为困难。
示例:
javascript">// Vue 2 <template><div><p>{{ count }}</p><button @click="increment">Increment</button></div> </template><script> export default {data() {return {count: 0};},methods: {increment() {this.count++;}} }; </script>
-
3. 生命周期钩子
-
Vue 3:
-
生命周期钩子变化:生命周期钩子的命名发生了变化,例如
beforeCreate
变为beforeCreate
,created
变为onCreated
,beforeMount
变为onBeforeMount
等。 -
setup 钩子:引入了
setup
钩子,可以在setup
中使用onBeforeMount
、onMounted
等生命周期钩子。
示例:
javascript">// Vue 3 <script> import { onMounted, onBeforeMount } from 'vue';export default {setup() {onBeforeMount(() => {console.log('Before Mount');});onMounted(() => {console.log('Mounted');});} }; </script>
-
-
Vue 2:
-
生命周期钩子:使用
beforeCreate
、created
、beforeMount
、mounted
等生命周期钩子。 -
逻辑组织:生命周期钩子在选项式 API 中使用,逻辑组织较为固定。
示例:
javascript">// Vue 2 <script> export default {beforeCreate() {console.log('Before Create');},created() {console.log('Created');},beforeMount() {console.log('Before Mount');},mounted() {console.log('Mounted');} }; </script>
-
4. 片段(Fragments)
-
Vue 3:
-
支持片段:Vue 3 支持片段(Fragments),允许一个组件返回多个根节点,无需额外的包裹元素。
示例:
javascript">// Vue 3 <template><div>First Element</div><div>Second Element</div> </template>
-
-
Vue 2:
-
不支持片段:Vue 2 不支持片段,一个组件必须有一个根节点。
示例:
javascript">// Vue 2 <template><div><div>First Element</div><div>Second Element</div></div> </template>
-
5. 递归组件
-
Vue 3:
-
递归组件:Vue 3 支持递归组件,可以在组件内部递归调用自身,无需额外的配置。
示例:
javascript">// Vue 3 <template><div><span>{{ label }}</span><ul v-if="children.length"><li v-for="child in children" :key="child.id"><TreeItem :node="child" /></li></ul></div> </template><script> import { defineComponent } from 'vue';export default defineComponent({name: 'TreeItem',props: {node: {type: Object,required: true}},computed: {children() {return this.node.children || [];}} }); </script>
-
-
Vue 2:
-
递归组件:Vue 2 也支持递归组件,但需要在组件选项中显式声明
name
属性。
示例:
javascript">// Vue 2 <template><div><span>{{ label }}</span><ul v-if="children.length"><li v-for="child in children" :key="child.id"><TreeItem :node="child" /></li></ul></div> </template><script> export default {name: 'TreeItem',props: {node: {type: Object,required: true}},computed: {children() {return this.node.children || [];}} }; </script>
-
6. 自定义渲染器
-
Vue 3:
-
自定义渲染器:Vue 3 提供了更灵活的自定义渲染器 API,可以更方便地创建自定义的渲染器,支持在不同环境中运行 Vue 应用,如 Web、Node.js、Weex 等。
示例:
javascript">// Vue 3 import { createRenderer } from 'vue';const renderer = createRenderer({// 自定义渲染器的选项insert: (el, parent, anchor) => {parent.insertBefore(el, anchor);},remove: (el) => {el.parentNode.removeChild(el);},// 其他方法... });const container = document.getElementById('app'); const vnode = { type: 'div', children: 'Hello, Vue 3!' }; renderer.render(vnode, container);
-
-
Vue 2:
-
自定义渲染器:Vue 2 的自定义渲染器支持较弱,扩展性有限。
-
7. 全局 API
-
Vue 3:
-
全局 API 变化:Vue 3 对全局 API 进行了重构,例如
Vue.extend
被移除,取而代之的是defineComponent
。 -
全局配置:全局配置对象
app
替代了Vue
的全局方法,例如app.config.globalProperties
替代了Vue.prototype
。
示例:
javascript">// Vue 3 import { createApp, defineComponent } from 'vue';const app = createApp(defineComponent({setup() {return {message: 'Hello, Vue 3!'};} }));app.config.globalProperties.$myGlobalMethod = () => {console.log('Global Method'); };app.mount('#app');
-
-
Vue 2:
-
全局 API:使用
Vue.extend
创建组件,Vue.prototype
设置全局属性等。
示例:
javascript">// Vue 2 import Vue from 'vue';Vue.prototype.$myGlobalMethod = () => {console.log('Global Method'); };new Vue({el: '#app',data() {return {message: 'Hello, Vue 2!'};} });
-
8. 组件内部的 this
-
Vue 3:
-
this 的变化:在组合式 API 中,
this
不再指向组件实例,而是undefined
,需要通过setup
函数的参数来访问组件的上下文。
示例:
javascript">// Vue 3 <script> import { ref, getCurrentInstance } from 'vue';export default {setup() {const count = ref(0);const instance = getCurrentInstance();const increment = () => {count.value++;console.log(instance.proxy); // 访问组件实例};return {count,increment};} }; </script>
-
-
Vue 2:
-
this 的使用:在选项式 API 中,
this
指向组件实例,可以方便地访问组件的属性和方法。
示例:
javascript">// Vue 2 <script> export default {data() {return {count: 0};},methods: {increment() {this.count++;console.log(this); // 访问组件实例}} }; </script>
-
9. 模板语法
-
Vue 3:
-
v-model 的变化:
v-model
支持多个参数,可以更灵活地使用v-model
。 -
v-for 的变化:
v-for
的语法更加严格,要求变量名和索引名不能相同。
示例:
<!-- Vue 3 --> <template><input v-model="name" /><input v-model.trim="name" /><input v-model.number="age" /> </template>
-
-
Vue 2:
-
v-model 的使用:
v-model
仅支持单个参数。 -
v-for 的使用:
v-for
的语法较为宽松,变量名和索引名可以相同。
示例:
<!-- Vue 2 --> <template><input v-model="name" /> </template>
-
10. 兼容性
-
Vue 3:
-
浏览器兼容性:Vue 3 支持现代浏览器,不再支持 IE11 及以下版本。
-
-
Vue 2:
-
浏览器兼容性:Vue 2 支持 IE11 及以上版本。
-
总结
Vue 3 在性能、API 设计、灵活性和扩展性方面都有显著提升,但同时也带来了一些学习成本。如果你的新项目需要更高的性能和更灵活的代码组织方式,推荐使用 Vue 3。