
Vue 是一套用于构建用户界面的渐进式框架,目前在全球拥有过亿的用户,是时下最热门的框架之一。它的核心库只关注视图层,更易上手,还便于与第三方库或既有项目整合。如今 Vue3.0 已经发布了一年多的时间了,经过时间的沉淀和市场的考验,Vue3 也于 2022 年 2 月 7 日正式成为新的默认版本。那么 Vue3 究竟做了那些升级改造呢?让我们来一起看一看吧。
性能提升
1.1 proxy 替代 Object.defineProperty 监听
Vue2.x 中采用 defineProperty 来劫持整个对象,然后进行深度遍历所有属性,给每个属性添加 getter 和 setter,实现响应式。Object.defineProperty 劫持数据:
(需要使用 vue.set, vue.delete)V. 劫持数组时需要特殊处理,重写覆盖部分 Array.prototype 原生方法;(['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'] 会改变原数组的原生方法不会被 Object.defineProperty 劫持,需要重新写数组的原生方法添加更新触发)Vue3 采用 proxy 重写了响应式系统,因为 proxy 相当于给对象的外层加了一层拦截,这层拦截可以做很多操作,比如对数据信息的过滤、修改、收集数据信息等,因为是在整个对象外层进行了拦截,所以,可以操作对象中的属性同时监听属性的新增、删除。proxy 是真正的对象本身进行劫持。II. 只在 getter 时才对对象的下一层进行劫持(优化了性能);1.2 源码体积
相比 Vue2.x, Vue3 整体体积变小了。Vue3.x 中除了移除了一些不常用的 API(如inline-template、filter等),更重要的是 Tree shanking。Tree shaking 是一种通过清除多余代码方式来优化项目打包体积的技术,专业术语叫 Dead code elimination, 简单来讲,就是在保持代码运行结果不变的前提下,去除无用的代码。它基于 ES6 模板语法(import与exports),主要是借助 ES6 模块的静态编译思想,编译时就能确定模块的依赖关系,以及输入和输出的变量,需要注意 import 和 export 是 ES6 原生的而不是通过 babel 或者 webpack 转化的。Vue3 中,对代码结构进行了优化,让其更加符合 Tree shaking 的结构,不会把所有的都打包进来,只会打包用到的 API,大大的减小了 Web 应用的体积。
1.3 diff算法优化
Vue3 在 diff 算法中相比 vue2.x 增加了静态标记。Vue2.x 是全量 Diff,Vue3.x 是静态标记 + 非全量 Diff。在 Vue2.x 中,当数据发生变化时,它就会新生成一个 DOM 树,并和之前的 DOM 树进行比较,找到不同的节点然后更新。这种比较的过程是全量的比较,这当中有些节点的内容不会发生改变,较为耗时。Vue3 在创建虚拟 DOM 的时候,会根据 DOM 中的内容是否会发生变化而添加静态标记( patchFlag ),只比对带有静态标记的节点,并且通过 Flag 的信息得知当前节点要比对的具体内容。1.4 hoistStatus 静态提升
Vue3 中对不参与更新的元素,会做静态提升,只会被创建一次,在渲染时直接复用。免去了重复创建的操作,优化运行时的内存占用。1.5 事件侦听器缓存
Vue2.x 中,绑定事件每次触发都要重新生成全新的 function 去更新,cacheHandlers 是 Vue3 中提供的事件缓存对象,当 cacheHandlers 开启,会自动生成一个内联函数,同时生成一个静态节点。当事件再次触发时,只需从缓存中调用即可,无需再次更新。开启 cacheHandlers 后,静态标记不存在了,这说明这部分内容不会在进行比较。
1.6 ssr渲染
Vue2.x 中也是有 SSR 渲染的,但是 Vue3 中的 SSR 渲染相对于 Vue2.x 来说,性能方面也有对应的提升。当静态内容大到一个量级的时候,会用 createStaticVNode 方法在客户端去生成一个 static node,这些静态 node,会被直接 innerHtml,就不需要再创建对象,然后根据对象渲染。
组合 API
Vue3 是向下兼容 Vue2 API 的,但是 Vue3 中提供了一种全新的 Composition API。Composition API(组合API)也是 Vue3 中最重要的一个功能,之前的 Vue2.x 版本采用的是 Options API(选项API),这种方式带来的问题就是随着功能增加,代码也越来复杂,再加上各种形式的组件间通信,导致了,每个功能模块的代码会散落分布在各个位置,这就加大了整个项目的阅读成本及维护成本。Vue3 的思路就是根据逻辑功能,对代码进行组织划分,把同一个功能的相关代码全都放在一起,或者把它们单独拿出来放在一个函数中,从而解决上述代码臃肿的问题。Composition API 必须要掌握的就是 setup() 函数。setup() 是作为使用 Composition API 的入口函数的使用的。它也是 Vue3 中新增的一个生命周期函数,它会在组件创建之前,props 被解析之后执行。2.1 setup 参数详解
setup() 函数接收两个参数(props、context)props 是响应式的,当传入新的 prop 时,它将被更新,需要注意正因为 props 是响应式,所以不能使用 ES6 进行解构,如果需要解构 props,可以通过使用 setup 函数中的 toRefs 来安全地完成此操作。props 对象将仅包含显性声明的 prop。并且,所有声明了的 prop,不管父组件是否向其传递了,都将出现在 props 对象中。其中未被传入的可选的 prop 的值会是 undefined。context 是一个普通的 JavaScript 对象,不是响应式的,可以正常使用 ES6 进行结构。1. attrs (非响应式对象,等同于 $attrs,获取当前标签上的所有属性的对象,但是该属性是props中没有声明接收的所有的对象);2. slots (非响应式对象,等同于 $slots,插槽);3. emit (方法,等同于 $emit,传递给父组件需要使用该事件);4. expose (函数,当封装组件时,介意 ref 暴露过多内容,可以用 expose 来约束一下输出)。2.2 setup 数据和方法如何使用?
setup 内部的属性和方法,必须 return 暴露出来,将属性挂载到实例上。
2.3 setup 内钩子函数及 watch、computed 是如何使用?
可以通过直接导入 onX 函数来注册生命周期钩子,放在 setup()函数内使用。computed 接受一个 getter 函数,并根据 getter 的返回值返回一个不可变的响应式 ref 对象;或者,接受一个具有 get 和 set 函数的对象,用来创建可写的 ref 对象。watch 侦听器数据源可以是一个具有返回值的 getter 函数,也可以直接是一个 ref。
选项式 API 的生命周期选项和组合式 API 之间的映射。2.3 reactive、ref 是什么?
reactive、ref 是 Vue3 的 Composition API 中两个最重要的响应式 API。reactive 只能为引用类型添加响应式。需要注意,如果给 reactive 传递了其他对象(如:时间对象),默认情况下修改对象,界面不会自动更新,想要更新,可通过重新赋值的方式。由于 reactive 不能对今本数据类型进行监听,导致开发过程中如果只想让某个变量实现响应数据就比较麻烦,为此 Vue3 提供了 ref 方法用来监听基本数据类型的变化, ref 底层的本质还是 reactive,系统会自动将 ref 传入的值转换成 reactive(即:ref(xx) =>reactive({value: xx})),在 teleport 中使用 ref 类型的数据不需要通过 value 获取。

新增组件
3.1 Fragment 参数详解
在 Vue2 中创建一个组件,只能有一个根节点,Vue3 中组件可以没有根标签, 内部会将多个标签包含在一个 Fragment 虚拟元素中,这样做的好处可以减少标签层级,减少内存占用。3.2 Teleport
Teleport 的作用是将渲染vue的组件内容到指定的 dom 节点中,解决了组建间 css 层级问题(多个 telepor 组件可以将其内容添加到同一目标元素)。
3.2 Suspense
Suspense 的作用是允许应用程序在等待异步组件时渲染一些后备内容,在等待时显示 fallback 的内容。

全面拥抱 TypeScript
TypeScript 是 JS 的一个超集,支持泛型、类型、命名空间、枚举等特性,弥补了 JS 在大型应用开发中的不足,使用 TypeScript 可以增加代码的可读性和可维护性。Vue3 的源码就是用 TypeScript 编写的,在 Vue3 中使用 TypeScript 不需要任何其他工具。最后,已有项目是否需要立刻升级到Vue3?
Vue3 应用到生产环境是完全没有问题,但是不是所有项目都要升级到 Vue3,不同公司、不同团队、不同的开发人员,还是要根据自身情况去定的,需要综合考虑开发者们的开发习惯和意愿、团队的开发资源、项目的稳定性等。ADVANCE.AI前端工程师
努力攀登的乐天派前端“晓”弟子

(Advance Intelligence Group)领创集团成立于2016年,致力于通过科技创新的本地化应用,改造和重塑金融和零售行业,以多元化的业务布局打造一个服务于消费者、企业和商户的生态圈。集团旗下包含企业业务和消费者业务两大板块,企业业务包含ADVANCE.AI和Ginee,分别为银行、金融、金融科技、零售和电商行业客户提供基于AI技术的数字身份验证、风险管理产品和全渠道电商服务解决方案;消费者业务Atome Financial包括亚洲最大的先享后付平台Atome和数字信贷服务。2021年9月,领创集团宣布完成超4亿美元D轮融资,融资完成后领创集团估值已超20亿美元,成为新加坡最大的独立科技创业公司之一。
