vm.$mount的执行

LiYajie: 2021-06-24 vue

# vm.$mount的执行流程

  1. _init()后面最终执行了vm.$mount(vm.$options.el)
if (vm.$options.el) {
  vm.$mount(vm.$options.el)
}
  1. 查找$mount声明位置

两个地方: 1. runtime/index.js中, 2. entry-runtime-with-compiler.js中

// entry-runtime-with-compiler.js

const mount = Vue.prototype.$mount // 缓存了runtime/index.js中的Vue.prototype.$mount方法

// 执行$mount的时候是执行的这个方法, 因为我们看的是compiler版本
// 这个方法是给runtime-compiler用的, 最终生成render函数
Vue.prototype.$mount = function (
  el?: string | Element,
  hydrating?: boolean
): Component {
  el = el && query(el) // document.querySelector 只是兼容了选择器和dom元素
  ...
  // 这里执行的就是runtime/index.js中的方法
  return mount.call(this, el, hydrating)
}
  1. runtime/index.js$mount
Vue.prototype.$mount = function (
  el?: string | Element,
  hydrating?: boolean
): Component {
  el = el && inBrowser ? query(el) : undefined
  return mountComponent(this, el, hydrating)
}

mountComponentlifecycle.js中定义了

→ 判断是否有render

→ 声明updateComponent

updateComponent = () => {
  vm._update(vm._render(), hydrating)
}

→ 执行new Watcher()

new Watcher(vm, updateComponent, noop, { // 渲染Watcher, 观察者模式
  before () {
    if (vm._isMounted && !vm._isDestroyed) {
      callHook(vm, 'beforeUpdate')
    }
  }
}, true /* isRenderWatcher */)

→ new Watcher()的构造函数中执行了一次this.get, 最终执行了updateComponent, 里面执行了vm._update()vm._render(), 实现了dom的挂载

→ 最终返回了vm

LiYajie 发布于: 2021-06-24