开篇语

接下来会写一个Vue.js的系列。网上有很多写Vue.js的文章,但大多是教你怎么使用Vue的。Vue已经是封装好的高级类库,Vue的使用手册,我觉得官网的教程就够了。所以,我并不打算写怎么使用Vue,而是学习它的实现原理,比如说,Vue构造函数,实例对象,组件实例,响应式原理,双向数据绑定,生命周期,v指令是实现,观察者模式,MVVM模式等等,在接下来的文章中都会慢慢讲解。

Vue构造函数

一个Vue创建的应用,至少有一个Vue根实例,组建也是vue实例。vue实例是通过构造函数Vue创建的。这个系列的重点不是讲解构造函数和原型,所以在这里不会过多的讲解。Vue构造函数会为vue实例实现各自的属性,至于方法,所有实例都可以共享,所以,应该把方法设置在Vue.prototype对象中,在vue实例的生命周期中会调用相应的函数。

通过Vue构造函数创建实例对象:

1
2
3
4
5
6
7
8
9
10
11
const vm = new Vue({
el:"#el",
data: {
},
method: {
},
computed: {
},
created: {
}
})

通过以上创建vue实例对象的示例,就算不看源码,我们也可以知道,Vue构造函数,有一个形参(假设是option),这是一个对象。

1
2
function Vue(option) {
}

Vue源码构造函数实现的实例里会有一些属性和方法。

1
2
3
4
function Vue(option) {
this.$el = ...;
this.$data = ...;
}

这些属性和方法的变量前缀都是$$,比如$el指向一个结点对象,$data指向data。

1
2
3
4
5
6
7
const data = {};
const vm = new Vue({
el: "#id",
data: data
});
vm.$data === data; // true
vm.$el === document.getElementById('id');//true

####创建组建实例传入的选项参数
vue组建也是vue实例i,所以创建传入的参数对象和创建根实例传入的参数的属性基本一样的。不过,需要注意的是data属性,必须是函数。每个Vue应用中只有一个根实例,但是可以有很多个vue组件实例,如果组建的data还是一个对象那么多个实例会引用同一个data对象,其中一个组建改变data,其他组建中的data也会改变,因为他们都指向同一个对象。

看看vue官网给出的例子:

1
2
3
4
5
<div id="example-2">
<simple-counter></simple-counter>
<simple-counter></simple-counter>
<simple-counter></simple-counter>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
var data = { counter: 0 }
Vue.component('simple-counter', {
template: '<button v-on:click="counter += 1">{{ counter }}</button>',
// 技术上 data 的确是一个函数了,因此 Vue 不会警告,
// 但是我们返回给每个组件的实例却引用了同一个 data 对象
data: function () {
return data
}
})
new Vue({
el: '#example-2'
})

这个例子中因为三个组件引用的是同一个data,所以,其中一个+1了,其他两个也会+1.