前端增长(vue进阶)(源码)

115 阅读2分钟

Vue中双向数据绑定是如何实现的?

  • vue2是使用defineProperty 准备一个Dep类,如下

准备一个Watch类,如下

new Vue ->

proxyData(所以通过vm就可以直接访问data) ->

observe (递归defineReactive,再执行defineProperty,get是添加观察者,即上面的addSub,set是触发更新,即上面的notify) ->

编译时,是将dom都转成Fragment的,在编译过程中分析出指令,节点类型等。如果解析到是v-model,就好进行new Watcher操作,然后自动监听input事件。

当要观察某个对象时,会实例化一个Watcher,在Watcher的get里,会触发observe里的get(即订阅),从而实现添加观察者,当要触发更新时,也触发watch里的update

  • vue3是使用Proxy

vue首次数据渲染是怎么样的?

调用runtime-with-compile里的$mount,把template转成render ->

调用runtime的$mount,执行里面的mountComponent方法,里面定义了updateComponent方法 ->

创建watcher对象,并把updateComponent传进去,然后执行watcher.get方法(创建虚拟dom并生成真实dom) ->

触发mount,挂载结束

Vue.set视图更新

对于数组,调用splice(vue代理过的splice)

对于对象,设置响应式 (defineReactive)

最后notify下

vuex实现原理

juejin.cn/post/690316…

diff算法是怎么样的

为什么要用key

当有相同标签名的元素切换时,需要通过key 特性设置唯一的值来标记以让Vue 区分它们,否则Vue 为了效率只会替换相同标签内部的内容。

watch和computed的实现区别

vue为什么能检查到数组的更新

对数组的原生方法进行了代理了

forceUpdate

$set原理

判断是否是原始值或者是undefined,null,是则返回。不是继续 ->

如果是数组,调用splice ->

如果是对象,且是已有的属性,直接返回设置的值 ->

如果该对象是vue或者是$data,直接返回设置的值 ->

如果该对象没有__ob__属性,直接返回设置的值 ->

调用defineReactive,发送notify通知,并返回设置的值

$delete原理

判断是否是原始值或者是undefined,null,是则返回。不是继续 ->

如果是数组,调用splice ->

如果该对象是vue或者是$data,直接返回 ->

如果是对象,且没有这个属性,直接返回 ->

删除 ->

如果该对象没有__ob__属性,直接返回 ->

发送notify通知

$watch原理

$watch不像delete,set都有静态方法,因为$watch需要vue实例。

获取当前vue实例vm ->

new Watcher() ->

判断是否有immediate属性,先执行一遍回调函数 ->

返回取消监听的函数

$nextTick原理

将cb放入callback数组中 ->

如果timerFun,把callback放入flushCallback(callback可以接收新的cb) ->

延迟调用优先级如下: Promise > MutationObserver > setImmediate > setTimeout ->

微任务(兼容不了的用宏任务)处理完后,处理flushCallback里的任务,即nextTick里的回调。