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实现原理
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里的回调。