文章目录
一、响应式原理api的改变
vue2使用的为defineProperty
,vue3使用的是proxy
1、defineProperty:
在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象
- 只代理对象上的某个属性
- 对象上定义新属性时,无法监听(为弥补这个问题,增加额外set、delete方法)
- 不能监听数组的变化
- 只有2个get, set方法
- 必须遍历对象的每个属性
- 必须深层遍历嵌套的对象
2、proxy:
用于定义基本操作的自定义行为
- Proxy代理整个对象,所以新增的属性也会被监听
- 可以弥补defineProperty的缺陷,数组方法可监听
- 有多达13种拦截方法
二 、diff算法的优化----静态标记
当视图更新时,只对动态节点部分进行diff运算,减少了资源的损耗。Patchflag是个枚举,取值为1代表这个元素的文本是动态绑定的,取值为2代表元素的class是动态绑定的。
vue2的diff算法是基于template重新渲染出一棵虚拟DOM树,然后对比,找出需要update哪里
vue3新增了静态标记patchflag
(动态数据所在的节点,例如{{msg}}等),可通过flag
信息得知当前节点要对比的具体内容
<div>
<p>云驻共创</p>
<p>如何评价 vue3</p>
<p>{{msg}}</p>
</div>
上面的例子其他都是静态节点不会改变,只有 <p>{{msg}}</p>
才会改变,Vue会生成新的虚拟DOM然后和旧的进行对比。
三 、生命周期的不同
如果要想在页面中使用生命周期函数,以往vue2的操作是直接在页面中写入生命周期,而vue3是需要去引用的,这就是为什么3能够将代码压缩到更低的原因
四、diff算法的优化----最长递增子序列
五、hoistStatic 静态提升
静态方法被提升到了渲染函数 render 之外,也就是静态提升。通过静态提升可以避免每次渲染的时候都要重新创建这些对象,从而大大提高了渲染效率。
vue2无论元素是否参与更新,每次都会重新创建然后再渲染。
vue3对于不参与更新的元素,会做静态提升,只会被创建一次,在渲染时直接复用即可。
六、cacheHandlers 事件侦听器缓存
vue2.x中,绑定事件每次触发都要重新生成全新的function去更新,cacheHandlers 是Vue3中提供的事件缓存对象,当 cacheHandlers 开启,会自动生成一个内联函数,同时生成一个静态节点。当事件再次触发时,只需从缓存中调用即可,无需再次更新。
七、ssr渲染
八、更好的Ts支持
vue2中使用ts有很多问题,比如
- ts作为一种编译时检查工具,只能原生+vue-class-component才可以实现,例如以下代码会将List推导为
[]nerver
类型
//---list无法使用---//
data () {
return {
list: [] // type: []never
}
}
//---只能这样写---//
data () {
return {
list: [] // type: []never
}
}
//---引入vue-class-component---//
import Vue from 'vue'
import Component from 'vue-class-component'
@Component
export default class HelloWorld extends Vue {
list: string[] = []
hello () {
list.push('Hello world')
}
}
九、Compostion API: 组合API/注入API
在vue2的组件内使用的是Option API风格(data/methods/mounted)来组织的代码,这样会让逻辑分散
而在vue3中,使用setup函数。一个组件功能逻辑代码都放在一个函数中完成。
十、更先进的组件
vue2必须有一个根节点
// vue2会发出警告,但是vue3会为我们创建一个虚拟节点Fragment
<template>
<div>华为云享专家</div>
<div>全栈领域博主</div>
</template>
十一、按需编译,体积比vue2.x更小
在 Vue 3 中,通过将大多数全局 API 和内部帮助程序移至 ES 模块导出来,实现了这一目标。这使现代的打包工具可以静态分析模块依赖性并删除未使用的导出相关的代码。模板编译器还会生成友好的 Tree-shaking 代码,在模板中实际使用了该功能时才导入该功能的帮助程序
十二、源码管理升级
Vue3采用了
Monorepo
的方式管理源码(将各个功能单独抽离出一个个单独的模块,各自打包,又能互相引用),多个代码库均放在一个仓库,在 packages 存放多个子项目,并且每个子项目都有自己的package.json。
主要有以下几个优点:
- 工作流的一致性:由于所有的项目放在一个仓库当中,复用起来非常方便,如果有依赖的代码变动,那么用到这个依赖的项目当中会立马感知到。并且所有的项目都是使用最新的代码,不会产生其它项目版本更新不及时的情况。
- 项目基建成本的降低:所有项目复用一套标准的工具和规范,无需切换开发环境,如果有新的项目接入,也可以直接复用已有的基建流程,比如 CI 流程、构建和发布流程。这样只需要很少的人来维护所有项目的基建,维护成本也大大减低。
- 团队协作也更加容易:一方面大家都在一个仓库开发,能够方便地共享和复用代码,方便检索项目源码,另一方面,git commit 的历史记录也支持以功能为单位进行提交,之前对于某个功能的提交,需要改好几个仓库,提交多个 commit,现在只需要提交一次,简化了 commit 记录,方便协作。
弊端:
- 单个项目体积较大
- 无法做权限管理