文章目录
1,双向绑定原理
Vue2使用Object.defineProperty 为每个属性创建getter和setter,通过getter和setter来捕获操作以实现响应式更新; 很多情况下,属性的新增和删除拦截不到(比如数组的长度变化)
Vue3 通过Proxy实现,proxy是ES6新特性,提供了更多的拦截操作;能监听到属性的删除和新增
v2 使用object.defineProperty来劫持数据的setter和getter方法,对象改变需要借助api去深度监听
v3 Proxy来实现数据劫持,删除了一些api($on,$once,$off) fiter等,优化了Block tree,solt,diff 算法等
Vue2在data中定义的数据就会自动遍历绑定Object.defineProperty以实现响应式;Vue3中要用ref包装,通过返回值的 .value属性获取响应式的值 ,修改也需要对 .value进行修改
v2 | 使用object.defineProperty来劫持数据的setter和getter方法,对象改变需要借助api去深度监听 |
v3 | Proxy来实现数据劫持,删除了一些api($on,$once,$off) fiter等,优化了Block tree,solt,diff 算法等 |
2,生命周期
Vue2 | Vue3 | |
beforeCreate() | setup() | 组件开始创建数据实例之前 |
created() | setup() | 组件实例完成 |
beforeMount() | onBeforeAMount() | DOM挂载之前 |
mounted() | onMounted() | DOM挂载完成 |
beforeUpdate() | onBeforeUpdate() | 组件更新之前 |
undated() | onUpdated() | 组件更新之后 |
beforeDestroy() | onBeforeunmount() | 组件销毁之前 |
destroyed() | onUnmounted() | 组件销毁之后 |
3,性能
- 数据监听机制
Vue2通过Object.defineProperty()进行数据劫持,需要遍历所有属性,有一定性能开销。
Vue3使用Proxy代理数据,直接监听对象,减少遍历属性时间,性能更好。
- 编译优化
Vue3对编译过程进行了优化,静态节点提升,缓存事件处理函数等,启动速度比Vue2快10-100倍。
- 包体积
Vue3移除了一些不常用的API,并优化了Tree-Shaking,使打包体积相比Vue2小10%左右。
- 内存占用
Vue3中移除了一些内存占用高的功能,同时优化了部分内存分配,降低内存消耗。
- SSR优化
Vue3使用异步SSR,大大减少主线程执行代码量,提升服务器端渲染性能。
Vue3可以说在初始化、渲染、内存占用等多个方面对Vue2有很大的性能提升,这使得Vue3可以承载更复杂的应用场景。
4.编码方式
- Options API 和 Composition API
Vue2通过Options API进行编码,逻辑分散,不便于重用。
Vue3引入Composition API,基于函数式编程,代码更聚合。
- definingComponent
Vue3通过definingComponent API定义组件,语法更清晰。
- Ref 和 Reactive
Vue3通过Ref和Reactive API声明响应式变量,语法更简洁。
- setup
Vue3中通过setup函数统一声明逻辑。Vue2逻辑分散在多个选项中。
- 异步组件
Vue3直接支持返回Promise的异步组件。
5,API
- Options API 和 Composition API
- Vue2中主要通过Options API进行开发,如data、methods等。
- Vue3推荐使用Composition API,如ref、reactive、watch、computed等。
- 移除过滤器(filter)
- Vue2中可以使用filter对数据进行转换后显示。
- Vue3移除了filter,推荐使用方法或计算属性代替。
- 全局和内实例API调整
- Vue3删除了一些不常用的全局和内实例API,并做了功能调整,如$on改为app.config.globalProperties。
- 源码级API
- Vue3暴露了部分源码API用于扩展,如createRenderer。
6,Diff 算法
- 静态标记
- Vue2 中通过标记静态根节点,跳过对这部分的Diff。
- Vue3 使用Shape Flags更精确地标记静态根,提高Diff效率。
- 优化逻辑
- Vue.js 2使用了比较经典的双指针(双端比较)的Diff算法。当进行Virtual DOM的更新时,Vue.js 2会比较新的Virtual DOM和旧的Virtual DOM,找出需要更新的节点并最小化更新DOM。
- Vue.js 3对Diff算法进行了优化,采用了更加高效的单端比较的Diff算法。在Vue.js 3中,每个VNode都有一个唯一的标识,这个标识在更新时被用来进行快速的节点匹配和查找。
- 分块对比
- Vue3 支持对相邻重复节点进行分块比较,减少冗余Diff。
- 如列表中连续相同文本节点进行合并比较。
- 异步渲染
- Vue3 支持组件异步渲染,等待组件完成再进行Diff。
- 避免无效对比,提高性能。
- 代码减少
- Vue3 对核心Diff逻辑进行了裁剪,移除了冗余代码。
- 优化后代码量减少超过40%。
- SSR Diff
- Vue3 新增了 SSR 环境下的 Diff 优化模式。
- 避免不必要客户端对比,加快渲染速度。
7,打包构建
- 打包体积
- Vue3移除了一些不常用的API,同时优化了Tree-shaking。
- 与Vue2相比,打包后体积减小约10%。
- 依赖优化
- Vue3对依赖进行了优化,裁剪不必要代码,减少冗余。
- 构建速度
- Vue3改进了编译过程,提高了构建速度。
- 特别是prod模式下打包速度明显加快。
- 编译优化
- Vue3改用优化的自动化持久缓存,加速增量编译。
- 配合新语法提升热重载速度。
- Tree-shaking
- Vue3编译支持更精确的Tree-shaking,删除无用代码。
- 如自动Tree-shaking样式表。
- 模块化
- Vue3源码实现了高度的ESM模块化。
- 更好的支持Tree-shaking、懒加载等能力。
- 新特性支持
- Vue3内置支持了碎片、Teleport、Suspense等新特性。
8.TypeScript支持
- 内部实现
- Vue2源码是JavaScript编写,需要手动维护类型定义。
- Vue3源码直接采用TypeScript重写,类型信息内置。
- 组件定义
- Vue2使用.vue文件,需要额外的vue-class-component decorators。
- Vue3可以直接以类的形式定义组件,更纯粹的TS体验。
- Options API
- Vue2的Options API缺乏类型推导。
- Vue3增强了对Options API的类型推导。
- Composition API
- Vue3的Composition API全面采用泛型、接口等TS新语法。
- 提供完整的类型支持。
- 引用注册
- Vue3改用统一的
defineComponent
方法注册组件。 - 提供完整的Props检验和IDE提示。
- TS配置
- Vue3优化了
tsconfig.json
,提供更严谨的TS类型检查。
- 内置工具类型
- Vue3导出了部分内置工具的TS类型,增强扩展性。
总体而言,Vue3对Vue2进行了全方位的升级:
- 性能上,Vue3做了很多优化,无论是初始化速度还是渲染效率都有显著提高。
- 功能上,Vue3添加了Composition API、Fragment、Teleport等前沿特性。
- 架构上,Vue3使用TypeScript重写了代码,整体架构更加清晰优雅。
- API上,废弃了一些API,新增了组合式API,提高了开发效率。
- 组织上,推荐函数式编程和hooks,使代码逻辑更加聚合。
- 构建上,改进了编译和Treeshaking,使打包速度和体积都得到优化。
- 生态上,Vue3的升级将促进相关工具链的进一步完善。
9.其他
1,vue3支持碎片化
v2中只能存在一个根节点,v3中可以保持如下多个根节点,一定程度上减少了标签的层级
注意:下列情况若子组件中存在多个根节点, 则使用组件时不能使用 v-show(无法对子组件根节点添加display)
解决: 1, 可用v-if代替(可能存在首次渲染失效) 2,只保留一个根节点
<template>
<div class="container">
<!-- 此时v-show无效 -->
<son v-show="false"></son>
</div>
</template>
-----son 组件
<template>
<div class="son_container">
1
</div>
<div class="son_container2">
2
</div>
<div class="son_container3">
3
</div>
</template>
总结:
1、setup 函数时,它将接受两个参数:(props、context(包含attrs、slots、emit))
2、setup函数是处于 生命周期函数 beforeCreate 和 Created 两个钩子函数之前的函数
3、执行 setup 时,组件实例尚未被创建(在 setup() 内部,this 不会是该活跃实例的引用,即不指向vue实例,Vue 为了避免我们错误的使用,直接将 setup函数中的this修改成了 undefined)
4、与模板一起使用:需要返回一个对象 (在setup函数中定义的变量和方法最后都是需要 return 出去的 不然无法再模板中使用)
5、使用渲染函数:可以返回一个渲染函数,该函数可以直接使用在同一作用域中声明的响应式状态
注意事项:
1、setup函数中不能使用this。Vue 为了避免我们错误的使用,直接将 setup函数中的this修改成了 undefined)
2、setup 函数中的 props 是响应式的,当传入新的 prop 时,它将被更新。但是,因为 props 是响应式的,你不能使用 ES6 解构,因为它会消除 prop 的响应性。
3.setup函数只能是同步的不能是异步的?
Vue的设计原则:Vue的设计哲学强调响应式和可预测性。异步的setup函数可能会导致组件的渲染时机变得不可预测,从而影响应用的性能和用户体验。
setup函数的执行环境:setup函数在组件的生命周期中执行的位置是在beforeCreate
和created
之间,此时组件的data
和methods
还没有完全初始化。由于异步操作可能会涉及到组件状态的改变,如果在setup函数中使用异步操作,可能会导致在数据和方法还未准备好时就去访问它们,从而引发错误。
避免错误使用:由于不能在setup函数中使用data
和methods
,Vue为了避免错误的使用,将setup函数中的this
修改成了undefined
。这种设计决策进一步强调了setup函数的同步执行需求,以确保组件的正确初始化。
返回值的重要性:在setup函数中定义的变量和方法最后都是需要return出去的,不然无法在模板中使用。这种设计要求确保了组件的状态和方法能够正确地被渲染和使用,而异步操作可能会打破这种设计原则,导致状态的不一致或渲染错误
2,指令与插槽不同
vue2:
vue2中使用slot可以直接使用slot;
v-for与v-if在vue2中优先级高的是v-for指令,而且不建议一起使用。
vue3:
vue3中必须使用v-slot的形式;
vue3中v-for与v-if,只会把当前v-if当做v-for中的一个判断语句,不会相互冲突;
vue3中移除keyCode作为v-on的修饰符,当然也不支持config.keyCodes;
vue3中移除v-on.native修饰符;
vue3中移除过滤器filter。
$on、$off 和 $once 实例方法用不了,意味着中央事件总线bus被弃用
移除app.componet注册全局组件
全局配置不再绑定到原型 globalPrexxxx
3,main.js文件不同
- vue2:vue2中我们可以使用pototype(原型)的形式去进行操作,引入的是构造函数。
- vue3:vue3中需要使用结构的形式进行操作,引入的是工厂函数;vue3中app组件中可以没有根标签。