从使用和原理两方面分析
原理
1 响应式原理
VUE2根据数据类型来做不同处理,数组和对象类型当值变化时如何劫持。
- 对象内部通过
defineReactive
方法,使用Object.defineProperty()
监听数据属性的 get 来进行数据依赖收集,再通过 set 来完成数据更新的派发; - 数组则通过重写数组方法来实现的。扩展它的 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
模板语法(import
与exports
),主要是借助ES6
模块的静态编译思想,在编译时利用ES6 Module
确定模块加载情况,以及它们的依赖关系,确认未被使用或引用的模块和变量,进而进行删除.
进一步了解tree-shaking: tree-shaking-test
3 静态标记PatchFlag
在Vue3.0中,模版编译时,编译器会在动态标签末尾加上 /* TEXT*/
PatchFlag。也就是在生成VNode的时候,同时打上标记,在这个基础上再进行核心的diff算法,并且 PatchFlag 会标识动态的属性类型有哪些;而Vue2.x的diff算法,会不断地递归调用 patchVNode,不断堆叠而成的几毫秒,最终就会造成 VNode 更新缓慢
进一步了解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
在vue3中,cacheHandler在首次渲染后缓存事件,并打上/*PROIPS*/
标记