Vue源码解析-响应式原理(计算属性、监听属性、组件更新)

Vue源码解析-响应式原理(计算属性、监听属性、组件更新)

计算属性&&监听属性

  • 了解计算属性实现原理
  • 了解监听属性实现原理和几种配置
  • 了解各自的适用场景

计算属性实现原理

类型:{ [key: string]: Function | { get: Function, set: Function } }

computed 中可以使用函数也可以使用对象,如果使用对象必须有 getter 属性。
computed 中定义的键值不能喝 dataprops 中的重复,否则报错。

何时开始计算?
在组件定义的之前完成 computed 的创建,此时不会开始计算,而是在 render 中触发了 getter 时触发计算。

📌 如果计算属性的值没有改变,不会触发 dep.notify 通知数据更新,不会触发重新渲染。

监听属性实现原理

new watcher 中收集依赖,不同的选项,收集依赖的方式不一样。

类型:{ [key: string]: string | Function | Object | Array }
一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个属性。

  • 选项:immediate

    在选项参数中指定 immediate: true 将立即以表达式的当前值触发回调:

    1
    2
    3
    4
    vm.$watch('a', callback, {
    immediate: true
    })
    // 立即以 `a` 的当前值触发回调
  • 选项:deep
    为了发现对象内部值的变化,可以在选项参数中指定 deep: true 。注意监听数组的变动不需要这么做。

    递归对象,收集每一个属性的依赖,实现数据监听。

    1
    2
    3
    4
    5
    vm.$watch('someObject', callback, {
    deep: true
    })
    vm.someObject.nestedValue = 123
    // callback is fired
  • 选项: sync
    sync:true 数据改变时,同步执行回调,会优先执行该 watch

适用场景

计算属性适合在模板渲染中,适合简单的逻辑,某个值是依赖了其他响应式对象甚者是计算属性而来的;

监听属性适用于观测某个值的变化去完成一段复杂的业务逻辑。

组件更新

渲染 watcher: 在数据更新的时候出发更新更是,触发 render, 生成 VNodeupdate 更新到 DOM

组件更新的过程核心就是新旧 vnode diff,对新旧节点相同以及不同的情况分别做不同的处理。
新旧节点不同的更新流程是创建新节点->更新父占位符节点->删除旧节点;
而新旧节点相同的更新流程是去获取它们的 children,根据不同情况做不同的更新逻辑。
最复杂的情况是新旧节点相同且它们都存在子节点,那么会执行 updateChildren 逻辑

原理图