Vue3源码类
Vue3
为何弃用defineProperty
Object.defineProperty
无法低耗费的监听到数组下标的变化,导致通过数组下标添加元素,不能实时响应;Object.defineProperty
只能劫持对象的属性,从而需要对每个对象,每个属性进行遍历。如果属性值是对象,还需要深度遍历。Proxy
可以劫持整个对象, 并返回一个新的对象。Proxy
不仅可以代理对象,还可以代理数组。- 可以代理动态增加的属性。
- 可以监听删除的属性。
- 监听数组的索引和 length 属性
除了使用Proxy
之外,Vue3
的快还体现在什么地方?
源码体积的优化
- 重写了虚拟
dom
不主动数据劫持
Vue2
里面的数据被劫持,均是defineProperty
主动为其添加getter\setter
方法的。Vue3
里面的数据劫持均为被动,对数据有操作,其才会被更改为响应式数据。- 体现在整个系统上,则起码在初始阶段,系统不会那么繁忙。
代码编译优化
- 使用了 组合
API
来代替vue2
中的Options API
- 组件内不需要根节点了,使用
fragment
(代码片段)代替了,fragment
(代码片段)不会在页面显示 vue3
中标记和提升所有的静态根节点,diff
的时候只需要对比动态节点内容
Composition Api
和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
实现原理
Q.E.D.