Vue源码解析-响应式原理(计算属性、监听属性、组件更新)
计算属性&&监听属性
- 了解计算属性实现原理
- 了解监听属性实现原理和几种配置
- 了解各自的适用场景
计算属性实现原理
类型:
{ [key: string]: Function | { get: Function, set: Function } }
在 computed
中可以使用函数也可以使用对象,如果使用对象必须有 getter
属性。
在 computed
中定义的键值不能喝 data
、props
中的重复,否则报错。
何时开始计算?
在组件定义的之前完成 computed
的创建,此时不会开始计算,而是在 render
中触发了 getter
时触发计算。
📌 如果计算属性的值没有改变,不会触发
dep.notify
通知数据更新,不会触发重新渲染。
监听属性实现原理
new watcher
中收集依赖,不同的选项,收集依赖的方式不一样。
类型:
{ [key: string]: string | Function | Object | Array }
一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用$watch()
,遍历watch
对象的每一个属性。
选项:
immediate
在选项参数中指定
immediate: true
将立即以表达式的当前值触发回调:1
2
3
4vm.$watch('a', callback, {
immediate: true
})
// 立即以 `a` 的当前值触发回调选项:
deep
为了发现对象内部值的变化,可以在选项参数中指定deep: true
。注意监听数组的变动不需要这么做。递归对象,收集每一个属性的依赖,实现数据监听。
1
2
3
4
5vm.$watch('someObject', callback, {
deep: true
})
vm.someObject.nestedValue = 123
// callback is fired选项:
sync
sync:true
数据改变时,同步执行回调,会优先执行该watch
适用场景
计算属性适合在模板渲染中,适合简单的逻辑,某个值是依赖了其他响应式对象甚者是计算属性而来的;
监听属性适用于观测某个值的变化去完成一段复杂的业务逻辑。
组件更新
渲染 watcher
: 在数据更新的时候出发更新更是,触发 render
, 生成 VNode
,update
更新到 DOM
。
组件更新的过程核心就是新旧 vnode diff
,对新旧节点相同以及不同的情况分别做不同的处理。
新旧节点不同的更新流程是创建新节点->更新父占位符节点->删除旧节点;
而新旧节点相同的更新流程是去获取它们的 children
,根据不同情况做不同的更新逻辑。
最复杂的情况是新旧节点相同且它们都存在子节点,那么会执行 updateChildren
逻辑