vue响应式原理

  1. MVVM框架的定义
  2. MVVM框架的意义
  3. VUE是个MVVM框架
  4. VUE是如何实现MVVM

https://cn.vuejs.org/images/data.png

vue核心是通过借助 Object.defineProperty 实现了观察者,使试图响应数据的变化。但并不是所有的数据改变都要重新渲染视图,所以vue还有个重要的部分是依赖搜集,依赖的意思是视图渲染所需要的数据。只有当这些数据改变时,vue才会触发重新渲染。

vue的数据双向绑定的代码在 core/observer 文件夹下。核心文件index.js,dep.js,watcher.js.

在index.js 里的 function defineReactive() 使用 Object.defineProperty 把数据转为 getter/setter。

依赖搜集的代码主要在 watcher.js 和dep.js(dependence依赖)。简单讲就是 watcher.js在收集dep.js.

一个vue实例有一个watcher对象。vue在生命周期钩子 beforeMount 之后, mounted之前进行依赖收集,因为vue会在这期间渲染试图, 所以可以知道视图需要那些数据,该部分代码在 instance/lifecycle.js 的function mountComponent(),

export function mountComponent (
...
  callHook(vm, 'beforeMount')
...
  new Watcher(vm, updateComponent, noop, {
    before () {
      if (vm._isMounted) {
        callHook(vm, 'beforeUpdate')
      }
    }
  }, true /* isRenderWatcher */)
...
  if (vm.$vnode == null) {
    vm._isMounted = true
    callHook(vm, 'mounted')
  }
  return vm
}

依赖收集的标志位是 Dep.target。watcher.js 实例化时,会调用function get(), 在方法里会调用dep.js 的 pushTarget,将watcher.js 实例赋给Dep.target。使Dep.target为真,让后开始收集依赖,代码的实现就是将dep的引用保存在watcher的deps数组里。

Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter () {
      const value = getter ? getter.call(obj) : val
      if (Dep.target) { // 标志位
        dep.depend()
...
      }
      return value
    },
    set: function reactiveSetter (newVal) {
...
    }
  })

猜你喜欢

转载自blog.csdn.net/blueblueuueew/article/details/80211766