https://zhuanlan.zhihu.com/p/...
vue是什么
每次在初始化vue,使用new Vue({})时, 不难发现vue是一个类.
通过一层层的查找,可以找到vue被定义的地方
// 路径 src/core/instance/index.js
function Vue(options){
...
this._init(options)
}
这里就是vue最初被定义的地方, 当执行new Vue时, 内部会执行一个this._init(options) 将初始化的参数传入~~~~
注意一点: 在Vue的内部,_符号开头的变量是供内部私有使用的.而$符号开头的变量是提供给外部用户使用的.
分析src/core/instance/index.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)
}
// 实例属性 实例方法
initMixin(Vue) // _init()方法
stateMixin(Vue) // $data/$props/ $set() $delete() $watch()
eventsMixin(Vue) // $emit() / $on() $off() $once() 事件相关方法
lifecycleMixin(Vue) // _update / $forceUpdate/ $destory 生命周期相关方法
renderMixin(Vue) // $nextTick()/ _render() // 渲染相关
export default Vue
将vue构造函数传入到以下方法中
initMixin(Vue) 定义_init()方法
stateMixin(Vue) 定义数据相关的方法 $set()/$delete()/$watch()
eventsMixin(Vue) 定义事件相关的方法 $emit()/$on()/$off()/$off()/$once
lifecycleMixin(Vue) 定义了_update() 以及生命周期相关的$forceUpdate/ $destory
renderMixin(Vue) 定义了 $nextTick() _render将render转化为渲染函数
这些方法都是在各自的文件中维护的
比如_init()
Vue.prototype._init = function (options) {
// 当调用_init方法时 先进行选项合并mergeOptions,将传入的选项和vue的原始选项进行合并操作
// 在进行一系列的初始化操作~~~~
}
在这些初始化完成之后,会初始化一些全局api initGlobalAPI(Vue)
export function initGlobalAPI(Vue){
Vue.set 方法
Vue.delete
Vue.nextTick
内置组件
keep-alive
transition
transition-group
initUse(Vue) Vue.use() 方法
initMixin(Vue) Vue.mixin()方法
initExtend(Vue) Vue.extend()
initAssetRegisters(Vue) Vue.component() Vue.directive() Vue.fitler()
}
Vue的架构设计
Vue架构是分层式的.最底层是es5的一个构造函数.再上层会定义一些_init,$watch,_render等方法. 再上层会在构造函数上定义一些全局的API, 比如set delete, nextTick等.接着是跨平台和服务端渲染以及编译器.最后导出一个完整的构造函数给用户使用.
目录结构
|-- dist 打包后的vue版本
|-- flow 类型检测,3.0换了typeScript
|-- script 构建不同版本vue的相关配置
|-- src 源码
|-- compiler 编译器
|-- core 不区分平台的核心代码
|-- components 通用的抽象组件
|-- global-api 全局API
|-- instance 实例的构造函数和原型方法
|-- observer 数据响应式
|-- util 常用的工具方法
|-- vdom 虚拟dom相关
|-- platforms 不同平台不同实现
|-- server 服务端渲染
|-- sfc .vue单文件组件解析
|-- shared 全局通用工具方法
- flow javascript是弱类型语言, 使用flow定义类型及检测类型.
- src/compiler 将template模板编译成render函数
- src/core 与平台无关通用代码, 可以运行在任何javascript平台上
- src/platforms 针对
web
平台和weex
平台分别的实现,并提供统一的API
供调用。 - src/observer vue监听数据变化, 以及改变视图
- src/vdom 将render函数转为vnode从而patch为真实dom 以及diff算法的实现
Vue版本
以ES module为例. 分为运行时版本和完整版本
注意在vue内部只认render函数.
new Vue({
data: {
message: '23123'
},
render(h){
return h('div', '213')
}
}).$mount('app')
但是我们在开发中只使用了template模板. 这是因为有vue-loader.它会将我们的template模板内定义的内容编译为render函数. 而这个编译过程就是区分完整版本和运行时版本的关键.完整版带有这个编译器,而运行时版本就不带.
请问runtime
完整版和runtime-only
运行版这两个版本的区别
- 带编译器的完整版会大6kb
- 编译时机不同, 编译器是运行时编译.性能会有一定损耗
而运行时版本是通过vue-loader做的离线编译.性能高
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。