vue源码解析(一)

CodeAstral
• 阅读 1547

vue源码解析

一、初始化

1.new Vue()


当我们new Vue({el:'#app',data:{}}) 时候,这是就要找到Vue的构造函数
该文件的路径为src\core\instance\index.js



Vue的构造函数  判断环境并且 立即调用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)
  }
}
点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
CodeAstral
CodeAstral
Lv1
试问岭南好不好。却道。此心安处是吾乡。
文章
9
粉丝
0
获赞
0