看源码技巧:一开始囫囵吞枣,别看细节。

vue源码目录:
dist目录输出格式应用场景:
vue.common.*.js cjs(CommonJS)模块版本 用于webpack1, browserfiry
vue.esm.*.js es6模块版本 用于webpack2+
vue.js umd模块版本,兼容cjs和amd 可同时用于node端和浏览器端
vue.runtime.js 不包含编译器,只包含运行时。

rollup只是用来打包的,适用于打包js,不像webpack什么都打包。

探寻入口文件:
new Vue({
el: '#app',
template: '<div></div>'或'#app', // 字符串模板
render: h => h(App) // render优先级比el高,
}).$mount("#app") // mount函数和指定el选项等同,写一个就行

指定模板来源中,render不存在是才考虑template和el,优先级:
render > template > el

组件初始化流程:new Vue() -> $mount() -> compile() -> render function -> Virtual DOM & Watcher(getter & setter) -> patch(update dom)
不管用何种方式去设置模板,最终都会变成一个render渲染函数。编译的过程,是将template字符串转换为render函数。

Vue构造函数(core/instance/index),_init()方法源码:

...
initMixin(Vue) 
stateMixin(Vue) 
eventsMixin(Vue) 
lifecucleMixin(Vue) 
renderMixin(Vue)
....

说明:
initMixin(Vue) 包含:initLifecycle, initEvents, initRender, beforeCreate, initInjections, initState, initProvide, created
stateMixin(Vue):包含$data, $props, $set, $delete, $watch
eventsMixin包含:$on, $emit, $once, $off
lifecycleMixin(Vue): _update, $forceUpdate, $destroy
renderMixin(Vue)包含:$nextTick, _render

其中,下划线方法_update, _render是私有的,不提供给用户使用。

数据响应化流程分析(srccoreinstancestate.js)的initState方法:
核心代码:

initData() {
 ...
 observe(data, true); // 返回一个Observer对象实例
 ...
}

Observer(src\core\observer\index.js):判断数据对象类型,做响应处理。

ES5继承用构造函数,ES6继承用class,都是语法糖。复杂度高,要求结构清晰的建议用class。

<parent>
  <child @click="onclick"></child>
</parent>
子组件标签上的监听事件虽然写在父组件里,但是实际监听和触发都是在子组件中。

vm.$createElement就是render(h)里面的h。

数组响应化原理:
vue如何实现observer和watcher源码:https://www.jb51.net/article/...
vue.js利用Object.defineProperty实现双向绑定:https://www.jb51.net/article/...


JohnsonGH
32 声望1 粉丝