vue源码解析
一、初始化
1.new Vue()
当咱们new Vue({el:'#app',data:{}}) 时候,这是就要找到Vue的构造函数该文件的门路为src\core\instance\index.jsVue的构造函数 判断环境并且 立刻调用this._init()办法,并把参数传入。function Vue (options) { 判断是否为生产环境并且 查看vue是否在this的prototype的原型上 // 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)定义$data,props,set,delete,watch,并且$data和$props是只读属性。stateMixin(Vue)初始化事件核心eventsMixin(Vue)初始化生命周期lifecycleMixin(Vue)初始化渲染函数renderMixin(Vue)export default Vue
Vue
就是一个Function实现的类,应用必须是new实例,而后调用this._init
办法
构造函数下方执行了很多办法(***MIixin(Vue)
),这些办法的作用就是给Vue
的prototype下面增加一些办法,这些办法是依照性能去定义的,别离在多个模块去实现。
2.this._init()
的过程
this._init(options)
该办法是在initMixin(Vue)
外面实现的。- 门路
src\core\instance\init.js
Vue: Class<Component> 指定传入参数为class类export function initMixin (Vue: Class<Component>) { 在Vue的原型下面增加_init()办法 负责vue的初始化过程。 Vue.prototype._init = function (options?: Object) { 获取vue的实例 const vm: Component = this 每个vue下面都有一个uid 让vueuid自增 保障vue的唯一性 vm._uid = uid++ vue实例不应该是一个响应式的,做个标记 vm._isVue = true ***************************************************************************** if (options && options._isComponent) { /** * 如果是子组件初始化时走这里,这里只做了一些性能优化 * 将组件配置对象上的一些深层次属性放到 vm.$options 选项中,以进步代码的执行效率 */ 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) 调用 beforeCreate 的生命周期 callHook(vm, 'beforeCreate') provide和reject传值 initInjections(vm) // resolve injections before data/props 数据初始化 响应式原理的外围,解决 props methods computed data watch 等 initState(vm) provide和reject传值 initProvide(vm) // resolve provide after data/props 调用 created 的生命周期 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) // } 判断数据中有没有el,如果有,主动执行$mount 没有的话,就要手动去挂载。 if (vm.$options.el) { vm.$mount(vm.$options.el) } }}
3.响应式原理initState(vm)
- initState在
import { initState } from './state'
- 同级目录下找到state.js
export function initState (vm: Component) { vm._watchers = [] const opts = vm.$options 解决props对象 为每一个props对象下面设置响应式 if (opts.props) initProps(vm, opts.props) 解决methods if (opts.methods) initMethods(vm, opts.methods) 初始化data, if (opts.data) { initData(vm) } else { observe(vm._data = {}, true /* asRootData */) } 解决conputed if (opts.computed) initComputed(vm, opts.computed) 解决watch if (opts.watch && opts.watch !== nativeWatch) { initWatch(vm, opts.watch) }}