前言
经过前面的铺垫,我们现在可以来到运行时了!在运行时中,Vue2又有怎样的运行逻辑呢?话不多说,让我们开始吧!
(BTW,介绍运行时的时候,我会先从一个更简单的运行时例子起手,等到后边相关的内容出现后再接上编译时的渲染函数那部分。)
创建实例
所以先来看一个最简单的运行时例子,也就是创建vue实例
css
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
在这个例子中,Vue2将如何运行呢?
javascript
/**
* Vue
* @param {*} options options 配置对象
*/
function Vue(options) {
this._init(options); // 使用的是Vue.prototype._init()
}
在这里_init()
是通过原型拓展的,Vue中的功能函数大多也是通过这一途径拓展的,接下来我们会看到越来越多类似的内容,暂且按下不表。
先来看看_init()
是如何拓展的:
javascript
/**
* 为Vue原型拓展Vue.prototype._init()
* @param {Vue} Vue原型
*/
function initMixin(Vue) {
Vue.prototype._init = function(options) {
}
}
scss
function Vue(options) {
this._init(options);
}
initMixin(Vue); // 在入口文件中执行该拓展代码
然后我们再来看看这个函数_init
究竟做了什么:
ini
function initMixin(Vue) {
Vue.prototype._init = function(options) {
const vm = this; // 实例创建时this指向对应的vue实例
// 设置属性
vm._uid = uid++;
vm._isVue = true;
vm.__v_skip = true;
vm._self = vm;
// js中对象是引用类型,所以以上操作会为内存中的对象添加这些属性
// ..._init()中很多设置属性的操作,为了先把基础的核心思想整理清楚,这里省略了一些操作,并且简化了一些操作,比如:
vm.$options = options;
initLifecycle(vm);
initEvents(vm);
initRender(vm);
callHook(vm, 'beforeCreate', undefined, false /* setContext */);
initInjections(vm);
initState(vm); // 数据初始化
initProvide(vm);
if (vm.$options.el) {
vm.$mount(vm.$options.el); // 进入挂载流程
}
}
}
_init()
中执行了多个初始化方法,但接下来我们将首先对initState()
进行整理,在这里我们将接触到Vue的核心------响应式中的数据劫持和数据代理。
总结
在这篇中,我们稍微了解了一下Vue实例的初始化步骤,为我们接下来对响应式数据的处理做一个铺垫。