一、Vue 3.0 性能提升主要是通过哪几方面体现的?
1、源码体积的优化
- 重写了虚拟 dom
2、响应式系统的升级
- 用 Proxy 和 Reflect 来代替 vue2 中的 Object.definepeoperty()方法来重写响应式
- vue3 中可以监听动态新增的属性
- vue3 中可以监听删除的属性
- vue3 中可以监听数组的索引和 length 属性
3、代码编译优化
- 使用了 组合 API 来代替 vue2 中的 Options API
- 组件内不需要根节点了,使用 fragment(代码片段)代替了,fragment(代码片段)不会在页面显示
- vue3 中标记和提升所有的静态根节点,diff 的时候只需要对比动态节点内容
二、Vue 3.0 所采用的 Composition Api 与 Vue 2.x 使用的 Options Api 有什么区别?
- 代码更利于维护和封装
- Vue2 中,我们会在一个 vue 文件的 data,methods,computed,watch 中定义属性和方法,共同处理页面逻辑 ,一个功能的实现,代码过于分散
- vue3 中,代码是根据逻辑功能来组织的,一个功能的所有 api 会放在一起(高内聚,低耦合),提高可读性和可维护性,基于函数组合的 API 更好的重用逻辑代码
- Vue3 中用 setup 函数代替了 Vue2 中的 befareCreate 和 created
- Vue3 中用 onUnmounted 代替了 Vue2 中的 beforeDestory
- Vue3 中用 unmounted 代替了 Vue2 中的 destroyed
三、Proxy 相对于 Object.defineProperty 有哪些优点?
- 代码的执行效果更快
- Proxy 可以直接监听对象而非属性
- Proxy 可以直接监听数组的变化
- Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的
- Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改
- Proxy 不需要初始化的时候遍历所有属性,另外有多层属性嵌套的话,只有访问某个属性的时候,才会递归处理下一级的属性
四、Vue 3.0 在编译方面有哪些优化?
- vue3.x 中标记和提升所有的静态节点,diff 的时候只需要对比动态节点内容
- Fragments(升级 vetur 插件): template 中不需要唯一根节点,可以直接放文本或者同级标签
- 静态提升(hoistStatic),当使用 hoistStatic 时,所有静态的节点都被提升到 render 方法之外.只会在应用启动的时候被创建一次,之后使用只需要应用提取的静态节点,随着每次的渲染被不停的复用
- patch flag, 在动态标签末尾加上相应的标记,只有带 patchFlag 的节点才被认为是动态的元素,会被追踪属性的修改,能快速的找到动态节点,而不用逐个逐层遍历,提高了虚拟 dom diff 的性能
- 缓存事件处理函数 cacheHandler,避免每次触发都要重新生成全新的 function 去更新之前的函数
- tree shaking 通过摇树优化核心库体积,减少不必要的代码量
五、Vue.js 3.0 响应式系统的实现原理?
- 通过 2 个响应式 API 函数的调用,一个是 reactive() , 一个是 ref(), 就可以大致明白了
- reactive 函数是用来把普通对象创建成为响应式对象的,函数内通过执行 proxy 创建的 get、set、deleteProperty 方法来实现
- get 方法获取响应式数据,同时调用 track 方法去收集依赖
- set 方法设置响应式数据,同时调用 trigger 方法是触发响应式数据的更新
- deleteProperty 方法删除响应式数据,同时用 trigger 方法是触发响应式数据的更新
- ref 函数是用来把一般类型的数据或者普通对象创建成为响应式对象的,函数内返回的是一个对象
- 对象内的 get 方法获取响应式数据,同时调用 track 方法去收集依赖
- 对象内的 set 方法设置响应式数据,同时调用 trigger 方法是触发响应式数据的更新
- tarck 函数内通过 targetMap 找到 depsMap 通过 depsMap 找到 dep,最后向 dep 内添加 effect()函数
- trigger 函数内通过 targetMap 找到 depsMap 通过 depsMap 找到 dep,最后遍历 dep 数组,执行里面的 effect()函数来更新响应式数据