vue responsive principle

  1. Definition of MVVM Framework
  2. The meaning of MVVM framework
  3. VUE is an MVVM framework
  4. How VUE implements MVVM

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

The core of vue is to implement the observer with the help of Object.defineProperty, so that it tries to respond to changes in data. But not all data changes need to re-render the view, so another important part of vue is dependency collection, which means the data needed for view rendering. Only when this data changes, vue will trigger a re-render.

The code for Vue's two-way data binding is in the core/observer folder. Core files index.js, dep.js, watcher.js.

The function defineReactive() in index.js uses Object.defineProperty to convert data to getter/setter.

The code for dependency collection is mainly in watcher.js and dep.js (dependence dependency). Simply put, watcher.js is collecting dep.js.

A vue instance has a watcher object. Vue performs dependency collection after the lifecycle hook beforeMount and before mounted, because Vue will render the attempt during this period, so you can know what data the view needs. This part of the code is in the function mountComponent() of instance/lifecycle.js,

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
}

The flag bit for dependency collection is Dep.target. When watcher.js is instantiated, function get() will be called, and pushTarget of dep.js will be called in the method, and the watcher.js instance will be assigned to Dep.target. Make Dep.target true to start collecting dependencies. The implementation of the code is to save the reference of dep in the deps array of the watcher.

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) {
...
    }
  })

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325642023&siteId=291194637