tangyuxian
文章79
标签37
分类5
vue-vue3与vue2对比分析(下)

vue-vue3与vue2对比分析(下)

从使用和原理两方面分析

原理

1 响应式原理

VUE2根据数据类型来做不同处理,数组和对象类型当值变化时如何劫持。
  1. 对象内部通过defineReactive方法,使用 Object.defineProperty() 监听数据属性的 get 来进行数据依赖收集,再通过 set 来完成数据更新的派发;
  2. 数组则通过重写数组方法来实现的。扩展它的 7 个变更⽅法(pop,push,reverse,shift,sort,splice,unshift),通过监听这些方法可以做到依赖收集和派发更新;

具体可参照本文分析:vue-响应式原理

VUE3使用Proxy,Proxy是ES6新特性,通过第2个参数handler拦截目标对象的行为

Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等),但在兼容性上放弃了IE11浏览器,具体兼容性可参照 MDN.

进一步了解Proxy可参照本文: es6-Proxy相关

2 打包优化tree-shaking

Tree shaking是一种通过清除多余代码方式来优化项目打包体积的技术,专业术语叫 Dead code elimination,它是基于ES6模板语法(importexports),主要是借助ES6模块的静态编译思想,在编译时利用ES6 Module确定模块加载情况,以及它们的依赖关系,确认未被使用或引用的模块和变量,进而进行删除.

进一步了解tree-shaking: tree-shaking-test

3 静态标记PatchFlag

在Vue3.0中,模版编译时,编译器会在动态标签末尾加上 /* TEXT*/ PatchFlag。也就是在生成VNode的时候,同时打上标记,在这个基础上再进行核心的diff算法,并且 PatchFlag 会标识动态的属性类型有哪些;而Vue2.x的diff算法,会不断地递归调用 patchVNode,不断堆叠而成的几毫秒,最终就会造成 VNode 更新缓慢

img

进一步了解diff算法:vue-diff算法

4 静态提升hoistStatic

在Vue中无论元素是否参与更新,每次都会重新创建,然后再渲染。如下图所示,每次都会createVNode;在Vue3中使用了静态提升后,对于不参与更新的元素,只会被创建一次,并打上打上 /*#__PURE__*/ 标记在渲染时直接复用即可

const { createVNode: _createVNode, createStaticVNode: _createStaticVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue

const _hoisted_1 = /*#__PURE__*/_createStaticVNode("<div><span class=\"foo\"></span><span class=\"foo\"></span><span class=\"foo\"></span><span class=\"foo\"></span><span class=\"foo\"></span></div>", 1)

return function render(_ctx, _cache) {
  return (_openBlock(), _createBlock("div", null, [
    _hoisted_1
  ]))
}

5 事件缓存cacheHandler

img

在vue3中,cacheHandler在首次渲染后缓存事件,并打上/*PROIPS*/标记

本文作者:tangyuxian
本文链接:https://www.tangyuxian.com/2022/02/27/%E5%89%8D%E7%AB%AF/vue/vue-vue3%E4%B8%8Evue2%E5%AF%B9%E6%AF%94%E5%88%86%E6%9E%90(%E4%B8%8B)/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可