@xiaoqq
2016-08-29T12:07:49.000000Z
字数 1839
阅读 997
Vue
Vue构造函数传入option
参数,主要属性有:
data
:Vue实例的数据对象。通过_proxy
方法可以将其属性递归地转为getter/setter,挂载在vue实例上。
function Vue(option) {
this.option = option || {};
this._data = option.data;
this._initData(this._data);
}
Vue.prototype._initData = function(data) {
Object.keys(data).forEach(key => {
this._proxy(key);
});
};
Vue.prototype._proxy = function(key) {
var self = this;
Object.defineProperty(this, key, {
get: function proxyGetter() {
return self._data[key];
},
set: function proxySetter(newVal) {
self._data[key] = newVal;
}
})
};
el
: 为实例提供挂载元素。值可以是 CSS 选择符,或实际 HTML 元素,或返回 HTML 元素的函数。Vue
中需要将所有属性递归地转成观察者Observer,当其值改变的时候,可以通知Wacher,并且执行其update
函数。
Observer为构造函数,传入参数value
,原型中拥有以下方法:
__ob__
: Observer实例本身walk
: Walk through each property and convert them into getter/setters.convert
: Convert a property into getter/setter so we can emit the events when the property is accessed/changed.还有两个辅助函数:
observe
:Attempt to create an observer instance for a value, returns the new observer if successfully observed, or the existing observer if the value already has one.defineReactive
: Define a reactive property on an Object.
function Observer(value) {
this.value = value;
this.walk(value);
}
Observer.prototype.walk = function(value) {
var that = this;
Object.keys(value).forEach(function(key) {
that.convert(that.value, key, that.value[key]);
});
}
Observer.prototype.convert = function(vm, key, value) {
defineReactive(vm, key, value);
}
function observer(value) {
if (!value || typeof value !== 'object') {
return;
}
return new Observer(value);
}
function defineReactive(vm, key, value) {
var dep = new Dep(); //每一个value都有watcher管理器,存放在闭包中
var childOb = observer(value);
Object.defineProperty(vm, key, {
enumerable: true,
configurable: true,
get: function getReactive() {
console.log('get value');
if (Dep.target) {
dep.addSub(Dep.target);
}
return value;
},
set: function setReactive(newVal) {
console.log('set value');
if (newVal === value) {
return;
}
childOb = observer(newVal);
value = newVal;
dep.notify();
}
})
}