Vue3 和 Vue2的区别
支持 monorepo 实现更好的项目管理
模块被拆分到不同的 package 中,每个 package 有各自的 API、类型定义和测试。这样做的好处有以下几点:
- 模块拆分更细化,职责划分更明确
- 模块之间的依赖关系也更加明确
- 开发人员也更容易阅读、理解和更改所有模块源码,提高代码的可维护性
- 一些 package(reactivity 响应式库等)是可以独立于 Vue.js 使用的。可单独依赖无需引用整个 Vue.js
对 TS 类型支持更加友好
Vue.js 3.0 自身采用了 TypeScript 进行开发。Vue2.x 采用 FaceBook 出品的 JavaScript 静态类型检查工具 Flow 进行管理。但是 Flow 对于一些复杂场景类型的检查,支持得并不好。
Composition API 和 Option API
Vue3 之前,一直使用的是 Options API,可以认为我们编写组件的工作就是对组件的配置项进行描述。通过按照 methods、computed、data、props 等这些不同的选项进行分类,当组件小的时候,这种分类方式一目了然这样编写的代码简单直观,易于上手。
但是当我们组件较大逻辑复杂时,我们修改一个逻辑需要去多个配置项里寻找,可读性和维护性就大大降低,并且 Options API 的 this 指向对 TS 并不友好。
diff 算法优化
之前是双向 diff 现在是 快速 diff 算法。
vue3 在初始化的时候会给每一个虚拟节点添加一个 patchFlags,是一种优化的标识。 只会比较 patchFlags 发生变化的节点,进行识图更新。而对于 patchFlags 没有变化的元素作静态标记,在渲染的时候直接复用。
响应式优化
之前 Object.defineProperty 不支持监听元素的删除和增加,也无法监听 map 和 set 等,用 Proxy 就可以解决这些问题。
资源体积优化
删除了一些冷门的 feature 并且引入了 tree shaking。
生命周期改变
创建前:beforeCreate -> 使用 setup() 创建后:created -> 使用 setup() 挂载前:beforeMount -> onBeforeMount 挂载后:mounted -> onMounted 更新前:beforeUpdate -> onBeforeUpdate 更新后:updated -> onUpdated 销毁前:beforeDestroy -> onBeforeUnmount 销毁后:destroyed -> onUnmounted 异常捕获:errorCaptured -> onErrorCaptured 被激活:onActivated 被包含在<keep-alive>
中的组件,会多出两个生命周期钩子函数。被激活时执行。 切换:onDeactivated 比如从 A 组件,切换到 B 组件,A 组件消失时执行
v-if 和 v-for
在 vue2 中 v-for 的优先级高于 v-if,可以放在一起使用,但是不建议这么做,会带来性能上的浪费
在 vue3 中 v-if 的优先级高于 v-for,一起使用会报错。可以通过在外部添加一个标签,将 v-for 移到外层