Skip to content
On this page

Vue3的优势

一、Vue 3.0 性能提升主要是通过哪几方面体现的?

1、update性能提高, vue3在性能方面比vue2快了1.3~2倍.

image-20201229205522651

image-20201229205522651

2、源码体积的优化 tree shaking 按需引入,减少不必要的代码量

  • 重写了虚拟 dom

image-20201229205522651

image-20201229205522651

image-20201229205522651

3、响应式系统的升级

  • 用 Proxy 和 Reflect 来代替 vue2 中的 Object.definepeoperty()方法来重写响应式

  • vue3 中可以监听动态新增的属性

  • vue3 中可以监听删除的属性

4、代码编译优化

  • 使用了 组合 API 来代替 vue2 中的 Options API

  • 组件内不需要根节点了,使用 fragment(代码片段)代替了,fragment(代码片段)不会在页面显示

  • vue3 中标记和提升所有的静态根节点,diff 的时候只需要对比动态节点内容

html
<template>
  <!-- 可以不需要在 套一个标签 -->
  <!-- <div> -->
    <h1>This is an about page</h1>
    <p>holle</p>
  <!-- </div> -->
</template>
<template>
  <!-- 可以不需要在 套一个标签 -->
  <!-- <div> -->
    <h1>This is an about page</h1>
    <p>holle</p>
  <!-- </div> -->
</template>

二、Vue 3.0 所采用的 Composition Api 与 Vue 2.x 使用的 Options Api 有什么区别?

  • 代码更利于维护和封装

  • Vue2 中,我们会在一个 vue 文件的 data,methods,computed,watch 中定义属性和方法,共同处理页面逻辑 ,一个功能的实现,代码过于分散

  • vue3 中,代码是根据逻辑功能来组织的,一个功能的所有 api 会放在一起(高内聚,低耦合),提高可读性和可维护性,基于函数组合的 API 更好的重用逻辑代码

三、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 的性能

html
<template>
  <div>
    <ul>
      <li>
        <!-- 不纳入虚拟dom 树遍历 -->
        <label>姓名</label>
        <!-- 添加 patchFlag 标记 -->
        <p>{{name}}</p>
      </li>
      <li>
        <!-- 不纳入虚拟dom 树遍历 -->
        <label>年龄</label>
        <!-- 添加 patchFlag 标记 -->
        <p>{{age}}</p> 
      </li>
    </ul>
  </div>
</template>
<template>
  <div>
    <ul>
      <li>
        <!-- 不纳入虚拟dom 树遍历 -->
        <label>姓名</label>
        <!-- 添加 patchFlag 标记 -->
        <p>{{name}}</p>
      </li>
      <li>
        <!-- 不纳入虚拟dom 树遍历 -->
        <label>年龄</label>
        <!-- 添加 patchFlag 标记 -->
        <p>{{age}}</p> 
      </li>
    </ul>
  </div>
</template>

image-20201229205522651

  • 缓存事件处理函数 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()函数来更新响应式数据