美文网首页
vue源码分析(三)解密new Vue()之前做了哪些不为人知工

vue源码分析(三)解密new Vue()之前做了哪些不为人知工

作者: vue爱好者 | 来源:发表于2020-03-19 09:55 被阅读0次

我们之前就说过vue是核心源码都是存放在src目录下面,接下来我们就看看src/core/index.js文件做了什么操作。

import Vue from './instance/index'
import { initGlobalAPI } from './global-api/index'
import { isServerRendering } from 'core/util/env'
import { FunctionalRenderContext } from 'core/vdom/create-functional-component'

initGlobalAPI(Vue)

......为了不增大篇幅,省略部分代码(大家可自行查看)

export default Vue

我们可以看看这里调用了一个initGlobalAPI(Vue) 方法,并且传入了一个vue对象作为参数,我们一步一步来,先看一下vue对象的来源文件(src/core/instance/index.js)。

import { initMixin } from './init'
import { stateMixin } from './state'
import { renderMixin } from './render'
import { eventsMixin } from './events'
import { lifecycleMixin } from './lifecycle'
import { warn } from '../util/index'

function Vue (options) {
  if (process.env.NODE_ENV !== 'production' &&
    !(this instanceof Vue)
  ) {
    warn('Vue is a constructor and should be called with the `new` keyword')
  }
  this._init(options)
}

initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)

export default Vue

可以看到定义了一个简单的函数Vue,并且调用了_init函数。至于_init在哪里定义的我们接下来再看。

接下来可以清楚的看到调用了如下5个函数:

initMixin(Vue)// 初始化_init函数

stateMixin(Vue) // 处理数据 ( “$data”、“$props”)

eventsMixin(Vue) // 挂载内部事件

lifecycleMixin(Vue) // 挂载内部生命周期

renderMixin(Vue) // 挂载内部渲染所需的方法

initMixin(Vue)

我们先找到src/core/instance/init.js文件。

export function initMixin (Vue: Class<Component>) {
  Vue.prototype._init = function (options?: Object) {
    ......为了不增大篇幅,省略部分代码(大家可自行查看)
  }
}

可以看到这个函数就是给Vue的原型对象上面注册了一个“_init”方法,其他什么都没干了。_init具体操作我们后面会再分析,现在先放过他。

stateMixin(Vue)

export function stateMixin (Vue: Class<Component>) {
  // flow somehow has problems with directly declared definition object
  // when using Object.defineProperty, so we have to procedurally build up
  // the object here.
  const dataDef = {}
  dataDef.get = function () { return this._data }
  const propsDef = {}
  propsDef.get = function () { return this._props }
  if (process.env.NODE_ENV !== 'production') {
    dataDef.set = function () {
      warn(
        'Avoid replacing instance root $data. ' +
        'Use nested data properties instead.',
        this
      )
    }
    propsDef.set = function () {
      warn(`$props is readonly.`, this)
    }
  }
  Object.defineProperty(Vue.prototype, '$data', dataDef)
  Object.defineProperty(Vue.prototype, '$props', propsDef)

  Vue.prototype.$set = set
  Vue.prototype.$delete = del

  Vue.prototype.$watch = function (
    expOrFn: string | Function,
    cb: any,
    options?: Object
  ): Function {
    const vm: Component = this
    if (isPlainObject(cb)) {
      return createWatcher(vm, expOrFn, cb, options)
    }
    options = options || {}
    options.user = true
    const watcher = new Watcher(vm, expOrFn, cb, options)
    if (options.immediate) {
      try {
        cb.call(vm, watcher.value)
      } catch (error) {
        handleError(error, vm, `callback for immediate watcher "${watcher.expression}"`)
      }
    }
    return function unwatchFn () {
      watcher.teardown()
    }
  }
}

可以看到上面对“$data”、“$props”属性都做了拦截操作,如果是开发环境对其进行赋值操作的话,都会引发一个“warn”的警告,代码如下:

Object.defineProperty(Vue.prototype, '$data', dataDef)
Object.defineProperty(Vue.prototype, '$props', propsDef)

最后在vue的“prototype”原型对象上面挂载了三个属性 “ $set”、“$delete”、“$watch”,我们在后面的会对他们进行分析。

eventsMixin(Vue)

这个函数主要是在vue的“prototype”原型对象上面挂载了几个自定义事件“$on”、“$once”、“$off”、“$emit”,对于这几个函数的用法大家都清楚了,我们后面会做详细的分析。

lifecycleMixin(Vue)

这个函数主要是在vue的“prototype”原型对象上面挂载了一些内部使用的生命周期函数“_update”、“$forceUpdate”、“$destroy”。一般以"$"开头或者以 _下划线开头的话,都是vue内部使用的。

renderMixin(Vue)

export function renderMixin (Vue: Class<Component>) {
  installRenderHelpers(Vue.prototype)
  Vue.prototype.$nextTick = function (fn: Function) {
    return nextTick(fn, this)
  }
  Vue.prototype._render = function (): VNode {
    ......为了不增大篇幅,省略部分代码(大家可自行查看)
  }
}

可以看到这个函数主要做了三件事情。

1、挂载一些实用的函数(installRenderHelpers(Vue.prototype)

2、在vue的“prototype”原型对象上面挂载“$nextTick”属性

3、在vue的“prototype”原型对象上面挂载“_render”属性

相关文章

网友评论

      本文标题:vue源码分析(三)解密new Vue()之前做了哪些不为人知工

      本文链接:https://www.haomeiwen.com/subject/rujkyhtx.html