vue.js源码学习分享(九)

vue

/*  */

var arrayKeys = Object.getOwnPropertyNames(arrayMethods);//获取arrayMethods的属性名称

/**

* By default, when a reactive property is set, the new value is//默认情况下,当一个响应的属性被设置,新的值也转换成响应的。然而当经过向下支撑时,我们不想促使转换,因为这值也许是一个嵌套值在一个冻结的数据结构,转换它时将会失去最优化

* also converted to become reactive. However when passing down props,

* we don't want to force conversion because the value may be a nested value

* under a frozen data structure. Converting it would defeat the optimization.

*/

var observerState = {

shouldConvert: true,

isSettingProps: false

};

/**

* Observer class that are attached to each observed//观察者类被绑定到每一个观察对象,一旦绑定,这个观察者使目标对象的属性键转换到getter/setter方法,收集依赖和发送的更新

* object. Once attached, the observer converts target

* object's property keys into getter/setters that

* collect dependencies and dispatches updates.

*/
接下来是最关键的一部分

var Observer = function Observer (value) {

this.value = value;

this.dep = new Dep();

this.vmCount = 0;

def(value, '__ob__', this);//给value定义一个‘——ob——’属性,属性的值为这个Observer对象

if (Array.isArray(value)) {//判断是不是一个数组

var augment = hasProto

? protoAugment

: copyAugment;

augment(value, arrayMethods, arrayKeys);

this.observeArray(value);

} else {

this.walk(value);

}

};

/**

* Walk through each property and convert them into//walk方法穿过每一个属性并且把他们转换到getter或者setter方法。这个方法应当仅在value的类型为对象时候调用

* getter/setters. This method should only be called when

* value type is Object.

*/

Observer.prototype.walk = function walk (obj) {

var keys = Object.keys(obj);//获取对象的每个键

for (var i = 0; i < keys.length; i++) {

defineReactive$$1(obj, keys[i], obj[keys[i]]);

}

};

/**

* Observe a list of Array items.//观察一个数组项目的列表

*/

Observer.prototype.observeArray = function observeArray (items) {

for (var i = 0, l = items.length; i < l; i++) {

observe(items[i]);

}

};

// helpers

/**

* Augment an target Object or Array by intercepting//增加一个目标对象或者数组通过用__proto__截取原型链

* the prototype chain using __proto__

*/

function protoAugment (target, src) {

/* eslint-disable no-proto */

target.__proto__ = src;

/* eslint-enable no-proto */

}

/**

* Augment an target Object or Array by defining

* hidden properties.//增大一个目标对象或者数组通过定义隐藏的属性

*/

/* istanbul ignore next */

function copyAugment (target, src, keys) {

for (var i = 0, l = keys.length; i < l; i++) {

var key = keys[i];

def(target, key, src[key]);

}

}

/**

* 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.//如果值已经有一个了则返回存在的观察者

*/

function observe (value, asRootData) {

if (!isObject(value)) {//如果value不是对象,那么就到此结束

return

}

var ob;

if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {

ob = value.__ob__;

} else if (

observerState.shouldConvert &&

!isServerRendering() &&

(Array.isArray(value) || isPlainObject(value)) &&

Object.isExtensible(value) &&

!value._isVue

) {

ob = new Observer(value);

}

if (asRootData && ob) {

ob.vmCount++;

}

return ob

}

/**

* Define a reactive property on an Object.//定义一个响应的属性在一个对象上

*/

function defineReactive$$1 (

obj,

key,

val,

customSetter

) {

var dep = new Dep();

var property = Object.getOwnPropertyDescriptor(obj, key);

if (property && property.configurable === false) {

return

}

// cater for pre-defined getter/setters//满足预定义的 getter/setters

var getter = property && property.get;

var setter = property && property.set;

var childOb = observe(val);

Object.defineProperty(obj, key, {

enumerable: true,

configurable: true,

get: function reactiveGetter () {

var value = getter ? getter.call(obj) : val;

if (Dep.target) {

dep.depend();

if (childOb) {

childOb.dep.depend();

}

if (Array.isArray(value)) {

dependArray(value);

}

}

return value

},

set: function reactiveSetter (newVal) {

var value = getter ? getter.call(obj) : val;

/* eslint-disable no-self-compare */

if (newVal === value || (newVal !== newVal && value !== value)) {

return

}

/* eslint-enable no-self-compare */

if ("development" !== 'production' && customSetter) {

customSetter();

}

if (setter) {

setter.call(obj, newVal);

} else {

val = newVal;

}

childOb = observe(newVal);

dep.notify();

}

});

}

/**

* Set a property on an object. Adds the new property and

* triggers change notification if the property doesn't

* already exist.

*/

function set (obj, key, val) {

if (Array.isArray(obj)) {

obj.length = Math.max(obj.length, key);

obj.splice(key, 1, val);

return val

}

if (hasOwn(obj, key)) {

obj[key] = val;

return

}

var ob = obj.__ob__;

if (obj._isVue || (ob && ob.vmCount)) {

"development" !== 'production' && warn(

'Avoid adding reactive properties to a Vue instance or its root $data ' +

'at runtime - declare it upfront in the data option.'

);

return

}

if (!ob) {

obj[key] = val;

return

}

defineReactive$$1(ob.value, key, val);

ob.dep.notify();

return val

}

/**

* Delete a property and trigger change if necessary.

*/

function del (obj, key) {

if (Array.isArray(obj)) {

obj.splice(key, 1);

return

}

var ob = obj.__ob__;

if (obj._isVue || (ob && ob.vmCount)) {

"development" !== 'production' && warn(

'Avoid deleting properties on a Vue instance or its root $data ' +

'- just set it to null.'

);

return

}

if (!hasOwn(obj, key)) {

return

}

delete obj[key];

if (!ob) {

return

}

ob.dep.notify();

}

/**

* Collect dependencies on array elements when the array is touched, since

* we cannot intercept array element access like property getters.

*/

function dependArray (value) {

for (var e = (void 0), i = 0, l = value.length; i < l; i++) {

e = value[i];

e && e.__ob__ && e.__ob__.dep.depend();

if (Array.isArray(e)) {

dependArray(e);

}

}

}

以上是 vue.js源码学习分享(九) 的全部内容, 来源链接: utcz.com/z/379942.html

回到顶部