其他章节请看:
vue 快速入门 系列
实例方法(或 property)和静态方法
在 Vue(自身) 项目结构 一文中,我们研究了 vue 项目自身构建过程,也知晓了 import Vue from 'core/index'
就是引入 vue
的核心代码,该文件的前两行对应着 vue 的实例方法和静态方法(或称全局方法),本篇就和大家一起来看一下这两部分。
// vuev2.5.20/src/core/index.js// 返回 Vue 构造函数,并准备好实例方法
import Vue from './instance/index'
// 静态方法(或称全局方法)
import { initGlobalAPI } from './global-api/index'
...
Tip:vuev2.5.20
只是 vue 克隆到本地的项目名,下面将默认是这个项目。
实例方法(instance/index.js)
instance/index.js
的内容并不复杂,全部代码不到 30 行:
// 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)
}
// 初始化相关。每次调用 new Vue() 就会被执行,里面包含很多初始化操作
initMixin(Vue)
// 状态相关。数据相关更确切
stateMixin(Vue)
// 事件相关
eventsMixin(Vue)
// 生命周期相关
lifecycleMixin(Vue)
// 渲染相关
renderMixin(Vue)
export default Vue
首先定义 Vue 构造函数,接着调用initMixin()
、stateMixin()
等 5 个方法,给 Vue 的原型添加方法(或 property)。以下是 initMixin()
、stateMixin()
的代码片段:
export function initMixin (Vue: Class<Component>) { Vue.prototype._init = function (options?: Object) {
...
}
}
export function stateMixin (Vue: Class<Component>) { ...
Object.defineProperty(Vue.prototype, '$data', dataDef)
Object.defineProperty(Vue.prototype, '$props', propsDef)
Vue.prototype.$set = set
Vue.prototype.$delete = del
Vue.prototype.$watch = function (
expOrFn: string | Function,
cb: any,
options?: Object
): Function {
...
}
}
剩余的三个方法也类似,也是给 Vue 的 prototype
增加方法。
以下是每个方法中在 Vue 的原型上定义的方法或 property:
initMixin(Vue) - _init()
stateMixin(Vue) - $data
、$props
、$set()
、$delete()
、$watch()
eventsMixin(Vue) - $on()
、$once()
、$off()
、$emit()
lifecycleMixin(Vue) - _update()
、$forceUpdate()
、$destroy()
renderMixin(Vue) - $nextTick()
、_render()
接着,我们将逐一分析其中的实现。
initMixin(初始化相关)
此方法仅仅给 Vue 定义了一个原型方法,即 _init()
。每次调用 new Vue()
就会被执行。
function Vue (options) { ...
this._init(options)
}
如果你看过 jQuery 的源码,里面也有一个类似的方法,是 init
。
var jQuery = function( selector, context ) { // 返回jQuery对象
return new jQuery.fn.init( selector, context, rootjQuery );
}
jQuery.fn = jQuery.prototype = {
constructor: jQuery,
init: function( selector, context, rootjQuery ) {
// 很多逻辑的处理
...
}
...
}
每次执行 jQuery(jqOptions)
都会调用 new jQuery.fn.init()
,里面有非常多的处理,所以我们可以给 jqOptions 传递多种不同类型的参数。
同样的,new Vue()
也支持多种参数,所以这个 _init()
里面也会做很多事情:
// 核心代码Vue.prototype._init = function (options?: Object) {
const vm: Component = this
// 合并参数
if (options && options._isComponent) {
initInternalComponent(vm, options)
} else {
vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {},
vm
)
}
// 初始化生命周期、初始化事件...
initLifecycle(vm)
initEvents(vm)
initRender(vm)
// 触发生命钩子:beforeCreate
callHook(vm, 'beforeCreate')
// resolve injections before data/props
// 我们可以使用的顺序:inject -> data/props -> provide
initInjections(vm)
initState(vm)
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created')
if (vm.$options.el) {
// 挂载
vm.$mount(vm.$options.el)
}
}
_init()
方法依次会合并参数、接着对生命周期、事件等做初始化,其中也会依次触发生命周期钩子 beforeCreate
和 created
,最后根据条件进行挂载。
stateMixin(数据相关)
stateMixin(Vue) 中 给 Vue 的原型定义的方法(或 property)有:$data
、$props
、$set()
、$delete()
、$watch()
。
vm.$data、vm.$props
vm.$data ,返回 Vue 实例观察的数据对象。
vm.$props,返回当前组件接收到的 props 对象。
vm.$set()、vm.$delete() 和 vm.$watch()
$set、$delete 和 $watch 都是与数据相关。出现的背景和原理分析请看 侦测数据的变化 - [vue api 原理]
eventsMixin(事件相关)
eventsMixin(Vue) 中定义的的原型方法有:$on
、$once
、$off
、$emit
。分别是注册事件,注册只触发一次的事件、解除事件、触发自定义事件。
vm.$on()
这四个方法,$on()
应该是核心,只有先注册事件,才能解绑事件,或触发事件。
用法如下:
vm.$on('test', function (msg) { console.log(msg)
})
vm.$emit('test', 'hi')
// => "hi"
以下是 $on()
的源码,核心功能就是“收集事件和对应的回调”:
Vue.prototype.$on = function (event: string | Array<string>, fn: Function): Component { const vm: Component = this
// 如果是数组,则遍历数组,依次注册
if (Array.isArray(event)) {
for (let i = 0, l = event.length; i < l; i++) {
vm.$on(event[i], fn)
}
} else {
// 将回调存入 event 对应的数组中
(vm._events[event] || (vm._events[event] = [])).push(fn)
...
}
return vm
}
vm.$once()
$once(),注册只触发一次的事件。
如果你看过 jQuery 源码(事件系统),也能猜到 $once 应该是基于 $on 来实现:
Vue.prototype.$once = function (event: string, fn: Function): Component { const vm: Component = this
// 回调的代理:先注销事件,在触发
function on () {
vm.$off(event, on)
fn.apply(vm, arguments)
}
on.fn = fn
// 在 $on 的基础上实现。给回调设置一个代理
vm.$on(event, on)
return vm
}
vm.$off()
$off(),解除事件绑定。
逻辑比较简单:支持没有传参的情况、传参是数组、解绑指定事件、解绑指定事件的回调。请看源码:
// 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)
}
// 初始化相关。每次调用 new Vue() 就会被执行,里面包含很多初始化操作
initMixin(Vue)
// 状态相关。数据相关更确切
stateMixin(Vue)
// 事件相关
eventsMixin(Vue)
// 生命周期相关
lifecycleMixin(Vue)
// 渲染相关
renderMixin(Vue)
export default Vue
0
vm.$emit()
$emit(),触发当前实例上的事件。
取得回调数组,依次触发回调。请看源码:
// 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)
}
// 初始化相关。每次调用 new Vue() 就会被执行,里面包含很多初始化操作
initMixin(Vue)
// 状态相关。数据相关更确切
stateMixin(Vue)
// 事件相关
eventsMixin(Vue)
// 生命周期相关
lifecycleMixin(Vue)
// 渲染相关
renderMixin(Vue)
export default Vue
1
lifecycleMixin(生命周期相关)
lifecycleMixin(Vue) 中给 Vue 定义的原型方法有:_update()
、$forceUpdate()
、$destroy()
。
vm.$forceUpdate()
迫使 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)
}
// 初始化相关。每次调用 new Vue() 就会被执行,里面包含很多初始化操作
initMixin(Vue)
// 状态相关。数据相关更确切
stateMixin(Vue)
// 事件相关
eventsMixin(Vue)
// 生命周期相关
lifecycleMixin(Vue)
// 渲染相关
renderMixin(Vue)
export default Vue
2
关键应该就是 vm._watcher.update()
通过全局搜索,发现 vm._watcher
赋值是在 watcher.js 的构造函数中(行{1}):
// 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)
}
// 初始化相关。每次调用 new Vue() 就会被执行,里面包含很多初始化操作
initMixin(Vue)
// 状态相关。数据相关更确切
stateMixin(Vue)
// 事件相关
eventsMixin(Vue)
// 生命周期相关
lifecycleMixin(Vue)
// 渲染相关
renderMixin(Vue)
export default Vue
3
于是我们知道 vm 的 _watcher 是一个 Watcher。而根据 侦测数据的变化 - [基本实现] 中对 Watcher 的研究,我们写过这样一段代码:
// 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)
}
// 初始化相关。每次调用 new Vue() 就会被执行,里面包含很多初始化操作
initMixin(Vue)
// 状态相关。数据相关更确切
stateMixin(Vue)
// 事件相关
eventsMixin(Vue)
// 生命周期相关
lifecycleMixin(Vue)
// 渲染相关
renderMixin(Vue)
export default Vue
4
调用 update()
,会通知到外界。这里的外界或许就是 vm,然后 vm 会做一些事情,其中或许就包含重新渲染。
vm.$destroy()
$destroy(),完全销毁一个实例。清理它与其它实例的连接,解绑它的全部指令及事件监听器。请看源码:
// 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)
}
// 初始化相关。每次调用 new Vue() 就会被执行,里面包含很多初始化操作
initMixin(Vue)
// 状态相关。数据相关更确切
stateMixin(Vue)
// 事件相关
eventsMixin(Vue)
// 生命周期相关
lifecycleMixin(Vue)
// 渲染相关
renderMixin(Vue)
export default Vue
5
Tip:vm._watchers
是在 Watcher 的构造函数中添加元素的,而在 vm.$watch
方法中就有 new Watcher()
,所以推测 vm._watchers
中的内容来自 vm.$watch
。
// 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)
}
// 初始化相关。每次调用 new Vue() 就会被执行,里面包含很多初始化操作
initMixin(Vue)
// 状态相关。数据相关更确切
stateMixin(Vue)
// 事件相关
eventsMixin(Vue)
// 生命周期相关
lifecycleMixin(Vue)
// 渲染相关
renderMixin(Vue)
export default Vue
6
// 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)
}
// 初始化相关。每次调用 new Vue() 就会被执行,里面包含很多初始化操作
initMixin(Vue)
// 状态相关。数据相关更确切
stateMixin(Vue)
// 事件相关
eventsMixin(Vue)
// 生命周期相关
lifecycleMixin(Vue)
// 渲染相关
renderMixin(Vue)
export default Vue
7
renderMixin(渲染相关)
renderMixin(Vue) 中给 Vue 定义的原型方法有:$nextTick()
、_render()
。
vm.$nextTick()
$nextTick(),将回调延迟到下次 DOM 更新循环之后执行
例如:
// 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)
}
// 初始化相关。每次调用 new Vue() 就会被执行,里面包含很多初始化操作
initMixin(Vue)
// 状态相关。数据相关更确切
stateMixin(Vue)
// 事件相关
eventsMixin(Vue)
// 生命周期相关
lifecycleMixin(Vue)
// 渲染相关
renderMixin(Vue)
export default Vue
8
根据用法我们可以猜测 $nextTick()
会将我们我们的回调先保存起来,然后再合适的时间再触发。请看源码:
// 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)
}
// 初始化相关。每次调用 new Vue() 就会被执行,里面包含很多初始化操作
initMixin(Vue)
// 状态相关。数据相关更确切
stateMixin(Vue)
// 事件相关
eventsMixin(Vue)
// 生命周期相关
lifecycleMixin(Vue)
// 渲染相关
renderMixin(Vue)
export default Vue
9
代码应该在 nextTick() 中:
export function initMixin (Vue: Class<Component>) { Vue.prototype._init = function (options?: Object) {
...
}
}
0
nextTick()
中,首先将我们的回调保存起来,将回调方法封装到一个匿名函数,然后再存入 callbacks
数组中。
什么时候触发回调?感觉行{1}处有秘密。事实证明我猜对了,请看源码:
export function initMixin (Vue: Class<Component>) { Vue.prototype._init = function (options?: Object) {
...
}
}
1
timerFunc 是一个函数,会根据条件选择不同的异步方法封装。这里有4种异步方法,Promise.then
和 MutationObserver
是微任务,后两种(setImmediate
和 setTimeout
)是宏任务。
已第一种为例:
export function initMixin (Vue: Class<Component>) { Vue.prototype._init = function (options?: Object) {
...
}
}
2
当我们执行 timerFunc()
时,就会立刻执行 p.then(flushCallbacks)
,flushCallbacks()
方法会依次执行回调函数,但 flushCallbacks()
方法只会在合适的时间被触发(即事件循环中)。
最后我们总结下:执行 this.$nextTick(fn)
,将进入 nextTick()
,首先将我们的回调函数用匿名函数封装起来,在将这个匿名函数扔在 callbacks
中,因为没有代办事项(let pending = false
),于是执行 timerFunc()
。
Tip: 有关事件循环、微任务和宏任务的介绍可以看这里
静态方法(global-api/index.js)
global-api/index.js
文件代码总共约 70 行,除去通过 import 导入的 20 行,剩余的都在 initGlobalAPI()
方法中:
export function initMixin (Vue: Class<Component>) { Vue.prototype._init = function (options?: Object) {
...
}
}
3
接着我们就源码的顺序依次分析。
Vue.set()、Vue.delete()和Vue.nextTick()
Vue.set() 是 vm.$set() 的别名
Vue.delete() 是 vm.$delete 的别名
Vue.nextTick() 是 vm.$nextTick() 的别名
Vue.observable()
代码很少:
export function initMixin (Vue: Class<Component>) { Vue.prototype._init = function (options?: Object) {
...
}
}
4
直接看官网介绍:
用法:让一个对象可响应。Vue 内部会用它来处理 data 函数返回的对象。
返回的对象可以直接用于渲染函数和计算属性内,并且会在发生变更时触发相应的更新。也可以作为最小化的跨组件状态存储器,用于简单的场景:
export function initMixin (Vue: Class<Component>) { Vue.prototype._init = function (options?: Object) {
...
}
}
5
initUse
export function initMixin (Vue: Class<Component>) { Vue.prototype._init = function (options?: Object) {
...
}
}
6
Vue.use()
initUse(Vue)
中只定义了 Vue.use()
这个全局方法。根据前面的源码分析,此方法的作用应该是安装插件。我们查阅 api 确认一下。
用法:安装 Vue.js 插件。如果插件是一个对象,必须提供 install 方法。如果插件是一个函数,它会被作为 install 方法。install 方法调用时,会将 Vue 作为参数传入。
Tip:到底什么是插件?官网:插件通常用来为 Vue 添加全局功能。插件的功能范围没有严格的限制——一般有下面几种:
添加全局方法或者 property。如:vue-custom-element
添加全局资源:指令/过滤器/过渡等。如 vue-touch
通过全局混入来添加一些组件选项。如 vue-router
添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。
一个库,提供自己的 API,同时提供上面提到的一个或多个功能。如 vue-router
这样说来,插件的用处挺大的。
Tip:与 jQuery 有些类似,jQuery 也提供了方法(如 jQuery.extend = jQuery.fn.extend = function() {}
)来扩展核心功能。
initMixin
export function initMixin (Vue: Class<Component>) { Vue.prototype._init = function (options?: Object) {
...
}
}
7
Vue.mixin()
initMixin(Vue) 中只定义了一个全局方法 Vue.mixin
。
mixin 有点类似 Object.assign 的味道。我们看一下官网的介绍:
用法:全局注册一个混入,影响注册之后所有创建的每个 Vue 实例。不推荐在应用代码中使用。
我们在看一下它的用法(来自官网):
export function initMixin (Vue: Class<Component>) { Vue.prototype._init = function (options?: Object) {
...
}
}
8
根据用法和源码,我们能推测出,Vue.mixin
就是将我们的参数合并到 Vue(this.options
) 中,后续创建 Vue 实例时这些参数就会有体现。
initExtend
Vue.extend()
initExtend(Vue) 中只定义了 Vue.extend()
这个全局方法。
extend
这个方法名,又让我想起 Object.assign、jQuery.extend
。让我们先看一下 api 如何介绍:
用法:使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。
好像猜错了。根据用法介绍,Vue.extend 的作用更像 es6 中 Class 的 extends。直接分析其源码再次验证我们的猜测:
export function initMixin (Vue: Class<Component>) { Vue.prototype._init = function (options?: Object) {
...
}
}
9
执行 Vue.extend()
将返回一个子类 Sub,该子类继承了父级(Vue)。为了提高性能,里面增加了缓存机制(行{1})。
initAssetRegisters
initAssetRegisters(Vue) 中定义了三个全局方法。
export function stateMixin (Vue: Class<Component>) { ...
Object.defineProperty(Vue.prototype, '$data', dataDef)
Object.defineProperty(Vue.prototype, '$props', propsDef)
Vue.prototype.$set = set
Vue.prototype.$delete = del
Vue.prototype.$watch = function (
expOrFn: string | Function,
cb: any,
options?: Object
): Function {
...
}
}
0
ASSET_TYPES
是一个数组:
export function stateMixin (Vue: Class<Component>) { ...
Object.defineProperty(Vue.prototype, '$data', dataDef)
Object.defineProperty(Vue.prototype, '$props', propsDef)
Vue.prototype.$set = set
Vue.prototype.$delete = del
Vue.prototype.$watch = function (
expOrFn: string | Function,
cb: any,
options?: Object
): Function {
...
}
}
1
Tip:如果你看过 jQuery,你也会发现有类似的写法,也就是当多个方法的逻辑相似,就可以写在一起,显得精简。
Vue.component()、Vue.directive()和Vue.filter()
直接看源码有点难懂(注释可稍后再看):
export function stateMixin (Vue: Class<Component>) { ...
Object.defineProperty(Vue.prototype, '$data', dataDef)
Object.defineProperty(Vue.prototype, '$props', propsDef)
Vue.prototype.$set = set
Vue.prototype.$delete = del
Vue.prototype.$watch = function (
expOrFn: string | Function,
cb: any,
options?: Object
): Function {
...
}
}
2
我们翻阅一下对应 api:
Vue.filter( id, [definition] ) - 注册或获取全局过滤器。
export function stateMixin (Vue: Class<Component>) { ...
Object.defineProperty(Vue.prototype, '$data', dataDef)
Object.defineProperty(Vue.prototype, '$props', propsDef)
Vue.prototype.$set = set
Vue.prototype.$delete = del
Vue.prototype.$watch = function (
expOrFn: string | Function,
cb: any,
options?: Object
): Function {
...
}
}
3
Vue.directive() - 注册或获取全局指令。
Vue.component() - 注册或获取全局组件
核心就是注册或获取。感觉作用比较简单,有点类似注册事件,取得事件的回调。现在我们在来看一下源码和相应的注释,会发现容易理解多了。
Tip:组件、指令、过滤器当然不是回调这么简单,所以我们可以猜测:这里只是负责注册和获取,至于如何生效,却不在此处。
分布它处的方法
vm.$mount()
如果 Vue 实例在实例化时没有收到 el 选项,则它处于“未挂载”状态,没有关联的 DOM 元素。可以使用 vm.$mount() 手动地挂载一个未挂载的实例。
项目中搜索 $mount
,发现有三个文件对其有定义 Vue.prototype.$mount =
:
platforms\web\runtime\index.js
platforms\weex\runtime\index.js
platforms\web\entry-runtime-with-compiler.js
前两个文件是根据不同的平台(web或weex)对 $mount 方法的不同的定义。
而最后一个文件有些意思,请看源码:
export function stateMixin (Vue: Class<Component>) { ...
Object.defineProperty(Vue.prototype, '$data', dataDef)
Object.defineProperty(Vue.prototype, '$props', propsDef)
Vue.prototype.$set = set
Vue.prototype.$delete = del
Vue.prototype.$watch = function (
expOrFn: string | Function,
cb: any,
options?: Object
): Function {
...
}
}
4
在 Vue(自身) 项目结构 一文中,我们知道 entry-runtime-with-compiler.js
生成的文件是完整版本(dist/vue.js
),完整版本是包含编译器的,而我们在 模板 一文中也知晓了编译器的主要作用,将模板编译成渲染函数。
所以我们能推测出这个 $mount(行{2}),就是在原始 $mount(行{1})中增加编译器的功能。
其他章节请看:
vue 快速入门 系列
还没有评论,来说两句吧...