vue源码系列-1初始化过程

vue源码系列-1初始化过程

起因

年初接手的学校的物理实验中心的系统也基本上完工了,现在在测试,准备上线阶段。
前后有7个人参加,有几个坚持了一两个月,一直坚持下来的有4个,写了大半年的代码,前端的11多行代码(git fame统计的提交情况)。从一个小白,现在已经emmm,还不能说大神,顶多就是随便一个页面都可以写出来吧,适配各种产品也ok。总之就是前端的基础都已经很熟了,后端也差不多。
然后很熟过后,考虑问题时自然就比最开始提升了一个层次,刚开始接手时,才刚刚能把vue界面看懂,写一些简单的页面,当时只想着做出来就行了,其他的先都不管,结果命名、文件位置、样式等都是乱的。
每次理解项目时都是凭着自己是管理整个项目的,对整理项目的结构很清楚,每个页面的文件在哪,每个功能涉及到哪些变量、函数以及其位置等都很清楚;但对于其他人就有点eeee,mmm。
然后就想着等这次上线后,在准备做第二版阶段,把整个系统的架构给整理清楚以及代码规范等都要制定清楚,这就放在以后再说。这系列文章的重点还是vue源码。
随着技术的提升, 随之一起的不只是对项目的架构的关注,还有思考的层次,以前没有想过性能;大一时也曾疯狂的刷过题,但当时就实在是不清楚理解这些算法有什么用?做学术研究?跟做数学题一样,很难提取兴趣,如果长时间没有成果,则很难再坚持下去。
然而,现在写代码的时候却时不时的往组织,效率和原理的方面考虑,怎样写使代码量最少、时间最快、以及整个流程其内部是怎么运行的。
然后再找资料的过程中,发现大部分都是与面试、源码有关的,并且自己也试着听了几节,结果很有用,解答了我很多积攒已久的困惑。然后现在的打算就是,把vue的源码和数据库性能优化学习完后就去面试。
先定个小目标,看能否在开学前学完,加油吧。
这里附上一句自己很喜欢的话:

每当你被漫天的乌云压的喘不过气时,往往是一切问题解决的时候。而当你感觉晴空万里时,其实并没你想得那样好。

入口

位置: src/platforms/web/entry-runtime-with-compiler.js
入口文件,覆盖$mount,执行模板解析和编译工作

//挂载方法,保存原来的$mount
const mount = Vue.prototype.$mount
//覆盖或扩展默认的$mount
Vue.prototype.$mount = function (
  el?: string | Element,
  hydrating?: boolean
): Component {
  el = el && query(el)

  /* istanbul ignore if */
  if (el === document.body || el === document.documentElement) {
    process.env.NODE_ENV !== 'production' && warn(
      `Do not mount Vue to <html> or <body> - mount to normal elements instead.`
    )
    return this
  }

  //解析option选项
  const options = this.$options
  // resolve template/el and convert to render function
	//先判断是否有render
  if (!options.render) {
    let template = options.template
	  // 模板解析
    if (template) {
      if (typeof template === 'string') {
        if (template.charAt(0) === '#') {
          template = idToTemplate(template)
          /* istanbul ignore if */
          if (process.env.NODE_ENV !== 'production' && !template) {
            warn(
              `Template element not found or is empty: ${options.template}`,
              this
            )
          }
        }
      } else if (template.nodeType) {
        template = template.innerHTML
      } else {
        if (process.env.NODE_ENV !== 'production') {
          warn('invalid template option:' + template, this)
        }
        return this
      }
    } else if (el) {
      template = getOuterHTML(el)
    }
    // 如果存在模板,执行编译
    if (template) {
      /* istanbul ignore if */
      if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
        mark('compile')
      }

      //得到渲染函数
      const { render, staticRenderFns } = compileToFunctions(template, {
        outputSourceRange: process.env.NODE_ENV !== 'production',
        shouldDecodeNewlines,
        shouldDecodeNewlinesForHref,
        delimiters: options.delimiters,
        comments: options.comments
      }, this)
      options.render = render
      options.staticRenderFns = staticRenderFns

      /* istanbul ignore if */
      if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
        mark('compile end')
        measure(`vue ${this._name} compile`, 'compile', 'compile end')
      }
    }
  }
  // 执行挂载
  return mount.call(this, el, hydrating)
}

src/core/index.js
定义全局API

//定义全局API
initGlobalAPI(Vue)

src\core\instance\index.js
定义构造函数

//构造函数
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)  //通过该方法给vue添加_init方法
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)

src/core/instance/init.js
初始化方法init定义的地方
定义实例方法
initMixin(Vue) //通过该方法给vue添加_init方法
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)

	 initLifecycle(vm)    // 声明 $parent, $root, $children, $refs
    initEvents(vm)      // 对父组件传入事件添加监听(@...)
    initRender(vm)     // 声明$slots, $createElement()
    callHook(vm, 'beforeCreate')  //调用beforeCreate的钩子
    initInjections(vm)   // 注入数据
    initState(vm)       // 重要:数据初始化,响应式
    initProvide(vm)    // 提供数据
    callHook(vm, 'created')

初始化过程

new Vue() :调用init
=> this._init(options) 初始化各种属性
=> $mount 调用mountcomponent()
=> mountcomponent() 申明updateComponent,创建watcher
=> _render() 获取虚拟dom
=> _update() 把虚拟dom转换为真实dom

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值