又看完一遍中文社区的教程接下来开始做vue2.0的源码解读了!
注:解读源码时一定要配合vue2.0的生命周期和API文档一起看
vue2.0的生命周期分为4主要个过程
-
create。 创建---实例化Vue(new Vue) 时,会先进行create。
-
mount。挂载---根据el, template, render方法等属性,会生成DOM,并添加到对应位置。
-
update。更新---当数据发生变化后,更新DOM。
-
destory。销毁---销毁时执行。
接下来再看看生命周期图是不是很明朗呢?
源码地址 https://github.com/vuejs/vue
带你们进入源码中看看new vue的简略过程
第一步 new Vue({})
G:vue-devsrccoreinstanceindex.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) //调用 init.js中 Vue.prototype._init } initMixin(Vue) //ctrl+鼠标左键跳入 stateMixin(Vue) eventsMixin(Vue) lifecycleMixin(Vue) renderMixin(Vue) export default Vue
注:以下源码太长不做全部复制简要截图(注意我会截行数)源码上去!
G:vue-devsrccoreinstanceinit.js
看到生命周期函数了吧!
在beforeCreate之前对 生命周期/事件/render 进行了初始化
beforeCreate和creted之间 执行的initState(vm) 函数 主要是对data/props/computed/watch等进行监听
create完毕之后看mount
G:vue-devsrccoreinstanceinit.js
点击$mount
进入G:vue-devflowcomponent.js
可以看出执行是Component方法
在这个文件中你可以看到vue的几乎全部接口,跳进来看了一遍发现应该是跳错了 不过我还是熟悉了一下里面的额接口
然后我搜索 Vue.prototype.$mount 找到G:vue-devsrcentriesweb-runtime-with-compiler.js
我之前有说过上面的东西没用么 没有吧(死鸭子嘴硬着呢!)
G:vue-devsrcentriesweb-runtime-with-compiler.js在改文件中主要对el, template, render 三个属性进行处理
const options = this.$options // resolve template/el and convert to render function 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, { shouldDecodeNewlines, delimiters: options.delimiters }, this) options.render = render options.staticRenderFns = staticRenderFns /* istanbul ignore if */ if (process.env.NODE_ENV !== 'production' && config.performance && mark) { mark('compile end') measure(`${this._name} compile`, 'compile', 'compile end') } } } return mount.call(this, el, hydrating)
这里分享一个看源码的小技巧
就是实在看不懂的时候去api 中找找也许能很好的帮助你理解 ----比如最后一个参数 (第一反应什么玩意啊)
有的时候甚至都不需要再回去看源码了 哈哈
今天就看到这 有时间继续
眼睛好疼啊!!!---可能发烧了
有人问 阅读源码有个卵用
如果你只是想用一下 当然没啥卵用了,而且只要按路上照规范来工作中也不会遇见很深的问题 但是如果你想再前端方向上走得远,玩的6666666你就需要深度阅读一下了,
比如上个文件 可以看出 render>template>el的 哈哈 但是我今天看到说单文件组件(.vue)写法 都会被整合成render的写法