vue源码阅读记录2-主文件

118 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情

vue源码阅读记录-主文件

按照上一章节打上debugger进入到vue实例里面有一下代码

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方法形参就是我们再new Vue时候传入的配置或者一些方法之类的options。这边做了一个在vue没有使用new关键词时的报错提示。接下来在Vue后面紧跟的几个参数都是xxxMixin,顾名思义是在Vue构造函数中混入一些东西,那具体怎么做呢。选择其中一个stateMixin来讲

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 =....


在阅读这块代码时候,我们先回忆下$data,$props,$set,$delete,$watch,他们都是vue提供的一些api,$data、$props可以直接获取当前组件的data和props. 从源码可以看出在$data$props中各绑定了一个get和set,get都是返回了this._datathis._props,而set时就会报错(执行this.$data = 1或执行this.$props = 1 就会报错)。随后又向$set和$delect、$watch各上绑定了一个方法方法,具体是什么,后面再去读。

在看initMixin 这个方法比较简单,就绑定了一个_init方法,_init方法后面在度

export function initMixin (Vue: Class<Component>) {
  Vue.prototype._init = function (options?: Object) {
      .....
  }
}

依次继续看eventsMixin绑定了$on、$once、$off、$emit方法。 继续看lifecycleMixin绑定了_update、$forceUpdate、$destroy方法。 继续看renderMixin绑定了$nextTick、_render、方法并且执行了installRenderHelpers方法,而installRenderHelpers 中又绑定了很多的以“_”开头的渲染辅助函数。

这边有个小技巧就是,开始阅读源码时劲量去手动的点开目录点击文件进去看,等目录和文件关系都熟悉后再使用编辑器自带的跳转功能。