Vue 首次渲染的过程

166 阅读1分钟

入口文件

  • 重写$mount函数
  • 完整版 src/platform/web/entry-runtime-with-compiler.js
    • el 不能是 body 或者 html 标签
    • 如果没有 render,把 template 转换成 render 函数
    • 如果有 render 方法,直接调用 mount 挂载 DOM
  • 运行时 src/platform/web/runtime/index.js
  • 区别
    • 完整版 支持template和render
    • 运行时
      • 不支持template编译
      • 返回mountComponent(),其内部校验了模板警告

初始化vm Vue.prototype._init

  1. initLifecycle(vm)
    • vm 的生命周期相关变量初始化
    • $children/$parent/$root/$refs
  2. initEvents(vm)
    • vm 的事件监听初始化, 父组件绑定在当前组件上的事件emit,emit,on,off,off,once
  3. initRender(vm)
    • vm 的编译render初始化
    • $slots/$scopedSlots/_c/$createElement/$attrs/$listeners
  4. callHook(vm, 'beforeCreate')
    • beforeCreate 生命钩子的回调
  5. initInjections(vm)
    • 把 inject 的成员注入到 vm 上
    • resolve injections before data/props
  6. initState(vm)
    • 初始化 vm 的 _props/methods/_data/computed/watch
  7. initProvide(vm)
    • 初始化 provide
    • resolve provide after data/props
  8. callHook(vm, 'created')
    • created 生命钩子的回调
  9. 调用 $mount() 挂载
  // expose real self
  vm._self = vm
  // vm 的生命周期相关变量初始化
  // $children/$parent/$root/$refs
  initLifecycle(vm)
  // vm 的事件监听初始化, 父组件绑定在当前组件上的事件
  initEvents(vm)
  // vm 的编译render初始化
  // $slots/$scopedSlots/_c/$createElement/$attrs/$listeners
  initRender(vm)
  // beforeCreate 生命钩子的回调
  callHook(vm, 'beforeCreate')
  // 把 inject 的成员注入到 vm 上
  initInjections(vm) // resolve injections before data/props
  // 初始化 vm 的 _props/methods/_data/computed/watch
  initState(vm)
  // 初始化 provide
  initProvide(vm) // resolve provide after data/props
  // created 生命钩子的回调
  callHook(vm, 'created')

首次渲染过程

  • Vue初始化,实例成员,静态成员
  • new Vue()
  • this._init() Vue构造函数内部调用_init(),_initMixin中注册_init方法
  • vm.$mount() _init()调用$mount()
  • mountComponent()
    • 触发beforeMount
    • 定义updateComponent
    • 创建Watcher实例
    • 触发mounted
  • watcher.get()