Vue 2 和 Vue 3 是 Vue.js 的两个主要版本,Vue 3 在基础架构和性能方面进行了显著的改进和优化,以提供更好的开发体验和性能表现。以下是 Vue 2 和 Vue 3 的一些主要区别:
1.响应式不同:
- Vue2的双向数据绑定是利用ES5的一个API Object.defineProperty对数据进行劫持,结合发布与订阅模式来实现的。
- Vue3中使用了ES6的Proxy API对数据代理。Proxy API具有更好的性能和更广泛的功能,使得在Vue3中能够更好地追踪对象的动态属性和数组的变化。
2. API不同:
- Vue2使用的是选项式API,data、methods、computed等,更适用于中小型项目
- Vue3引入了组合式API,同时也是兼容选项式API的。对于大型项目更加友好
- 组合式API更加直观和易于理解,使得代码结构更清晰,更好的逻辑复用,更灵活的代码组织,也更容易进行单元测试。
3. 生命周期函数不同:
- **Vue2**:beforeCreate、created、beforeMount、mounted、beforeUpdate、updated
**Vue3**:setup、onBeforeMount、onMounted、onBeforeUpdate、onUpdated
4. 定义变量和方法不同:
- Vue2中,data存放数据,methods中存放方法
- Vue3中,把数据和方法都放到setup方法中声明,setup在组件初始化构造的时候就会触发
5. 父子传参不同:
- 在Vue 2中,父组件向子组件传递参数通常使用props,而子组件向父组件传递参数可以使用`$emit`方法。具体来说,在父组件中通过给子组件绑定属性的方式将数据传递给子组件,然后子组件通过props接收父组件传递过来的值,并在需要时使用`this.$emit`触发一个自定义事件,将数据传递回父组件。
- 在Vue 3中,推荐使用`emits`选项来声明子组件需要触发的事件,然后在子组件中使用`ctx.emit`方法触发事件。`ctx`是一个包含了`attrs`、`slots`、`emit`等属性的上下文对象,其中`attrs`包含了父组件传递过来的所有属性,`slots`包含了子组件插槽相关的内容,`emit`是一个函数,用于触发自定义事件
6. diff算法不同:
- Vue2使用的是基于递归的双指针的diff算法,而vue3使用的是基于数组的动态规划的diff算法。Vue3的算法效率更高,因为它使用了一些优化技巧,比如按需更新、静态标记等。
- Vue2的diff算法对于列表渲染时的元素重新排序会比较低效,需要通过给每个元素设置唯一的key来提高性能。而vue3的diff算法在列表渲染时,通过跟踪元素的移动,可以更好的处理元素的重新排序,无需设置key。
- Vue2的diff算法会对整个组件树进行完整的遍历和比较,而vue3的diff算法会跳过静态节点的比较,只对动态节点进行更新。这减少了不必要的比较操作,提高了性能。
- Vue3的diff算法对于静态节点的处理更加高效,静态节点只会在首次渲染时被处理,后续更新时会直接跳过比较和更新操作,减少了不必要的计算。
7. 模板指令的变化:
- 如v-model:
- Vue2中,在组件上使用 `v-model` 相当于绑定 `:value` prop 并触发 `input` 事件
- Vue3中,自定义组件上的 `v-model` 相当于传递了 `modelValue` prop 并接收抛出的 `update:modelValue` 事件
- v-if和v-for的优先级:
- 2.x 版本中在一个元素上同时使用 `v-if` 和 `v-for` 时,`v-for` 会优先作用,每次渲染都会重新执行v-for循环,可能导致性能问题。
- 3.x 版本中 `v-if` 总是优先于 `v-for` 生效
8. IDE支持的升级:
- 由Vetur改成了Volar
9.其他一些:
- Vue3还支持TypeScript,提供了更多的类型定义文件和工具
- Fragments片段支持,可以有多个根节点
- 对TreeShaking有更好的支持,更精确的消除未使用的代码,减小打包体积等等