优秀的编程知识分享平台

网站首页 > 技术文章 正文

Vue源码全面解析四 initMixin函数(定义_init函数)

nanyue 2024-09-06 20:22:49 技术文章 8 ℃


我们首先打开"/src/core/instance/init.js"文件,可以看到代码如下:

export function initMixin (Vue: Class<Component>) {
  Vue.prototype._init = function (options?: Object) {
    const vm: Component = this
    // a uid
    vm._uid = uid++

    let startTag, endTag
    /* istanbul ignore if */
    if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
      startTag = `vue-perf-start:${vm._uid}`
      endTag = `vue-perf-end:${vm._uid}`
      mark(startTag)
    }

    // a flag to avoid this being observed
    vm._isVue = true
    // merge options
    if (options && options._isComponent) {
      // optimize internal component instantiation
      // since dynamic options merging is pretty slow, and none of the
      // internal component options needs special treatment.
      initInternalComponent(vm, options)
    } else {
      vm.$options = mergeOptions(
        resolveConstructorOptions(vm.constructor),
        options || {},
        vm
      )
    }
    /* istanbul ignore else */
    if (process.env.NODE_ENV !== 'production') {
      initProxy(vm)
    } else {
      vm._renderProxy = vm
    }
    // expose real self
    vm._self = vm
    initLifecycle(vm)
    initEvents(vm)
    initRender(vm)
    callHook(vm, 'beforeCreate')
    initInjections(vm) // resolve injections before data/props
    initState(vm)
    initProvide(vm) // resolve provide after data/props
    callHook(vm, 'created')

    /* istanbul ignore if */
    if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
      vm._name = formatComponentName(vm, false)
      mark(endTag)
      measure(`vue ${vm._name} init`, startTag, endTag)
    }

    if (vm.$options.el) {
      vm.$mount(vm.$options.el)
    }
  }
}

可以看到initMixin函数值做了一件事情,那就是给vue原型对象上面定义_init函数,这个就是给function Vue函数里面调用的。

我们来简单说说_init函数的工作:

1、记录当前实例的uid

2、合并实例参数

3、初始化生命周期标识

4、初始化渲染所需的函数

5、触发beforeCreate生命周期

6、处理inject参数

7、处理props、methods、data、computed、watch参数

8、处理provide参数

9、触发created生命周期

10、调用$mount函数

接下来我们具体看看代码:

const vm: Component = this
// a uid
vm._uid = uid++

定义了vm变量,并且赋值了_uid属性。

vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {},
vm
)

合并vue实例的参数选项,会对props、inject、directives等选项进行处理,返回一个新的对象。

initLifecycle(vm) // 初始化生命周期标识

initEvents(vm) // 处理附加的事件

initRender(vm) // 初始化渲染所需的函数

callHook(vm, 'beforeCreate') // 触发beforeCreate生命周期

initInjections(vm) // 处理inject参数

initState(vm) // 处理props、methods、data、computed、watch参数

initProvide(vm) // 处理provide参数

callHook(vm, 'created') // 触发created生命周期

为了避免篇幅过长,避免阅读疲劳,关于以上函数的具体分析我们用单独的篇章进行分析。

if (vm.$options.el) {
vm.$mount(vm.$options.el)
}

最后判断是否存在el挂载对象,然后调用$mount函数。

最近发表
标签列表