vue.js源码学习分享(九)
/* */ 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源码学习分享(九)的更多相关文章
- vue.js源码学习分享(一)
今天看了vue.js源码 发现非常不错,想一边看一遍写博客和大家分享 /** * Convert a value to a string that is actually rendered. *转换 ...
- vue.js源码学习分享(七)
var _Set; /* istanbul ignore if */ if (typeof Set !== 'undefined' && isNative(Set)) { // use ...
- vue.js源码学习分享(六)
/* */ /* globals MutationObserver *///全局变化观察者 // can we use __proto__?//我们能用__proto__吗? var hasProto ...
- vue.js源码学习分享(八)
/* */ var uid$1 = 0; /** * A dep is an observable that can have multiple * directives subscribing() ...
- vue.js源码学习分享(五)
//配置项var config = { /** * Option merge strategies (used in core/util/options)//选项合并策略 */ optionMerge ...
- vue.js源码学习分享(四)
/** * Generate a static keys string from compiler modules.//从编译器生成一个静态键字符串模块. */ function genStaticK ...
- vue.js源码学习分享(三)
/** * Mix properties into target object.//把多个属性插入目标的对象 */ function extend (to, _from) { for (var key ...
- vue.js源码学习分享(二)
/** * Check if value is primitive//检查该值是否是个原始值 */ function isPrimitive (value) { return typeof value ...
- Vue.js 源码学习笔记
最近饶有兴致的又把最新版 Vue.js 的源码学习了一下,觉得真心不错,个人觉得 Vue.js 的代码非常之优雅而且精辟,作者本身可能无 (bu) 意 (xie) 提及这些.那么,就让我来吧:) 程序 ...
随机推荐
- NOIP模拟赛 czy的后宫3
[题目描述] 上次czy在机房妥善安排了他的后宫之后,他发现可以将他的妹子分为c种,他经常会考虑这样一个问题:在[l,r]的妹子中间,能挑选出多少不同类型的妹子呢? 注意:由于czy非常丧尸,所以他要 ...
- 初涉manacher
一直没有打过……那么今天来找几道题打一打吧 manacher有什么用 字符串的题有一类是专门关于“回文”的.通常来说,这类问题要么和一些dp结合在一起:要么是考察对于manacher(或其他如回文自动 ...
- 第7课 Thinkphp 5 模板输出变量使用函数 Thinkphp5商城第四季
目录 1. 手册地址: 2. 如果前面输出的变量在后面定义的函数的第一个参数,则可以直接使用 3. 还可以支持多个函数过滤,多个函数之间用"|"分割即可,例如: 4. 变量输出使用 ...
- IOC容器和Bean的配置
IOC容器和Bean的配置 1 IOC和DI ①IOC(Inversion of Control):反转控制. 在应用程序中的组件需要获取资源时,传统的方式是组件主动的从容器中获取 ...
- JAVA基础篇—Servlet小结
一.get请求和post请求的区别: 1.get请求是通过url传递参数,post请求是通过请求体传递参数的 2.get请求最多允许传递255个字符,对长度有限制,所以数据比较大的时候我们使用post ...
- 排序 sort函数
sort函数见下表: 函数名 功能描述 sort 对给定区间所有元素进行排序 stable_sort 对给定区间所有元素进行稳定排序 partial_sort 对给定区间所有元素部分排序 partia ...
- 对java多线程的一些浅浅的理解
作为一名JAVA初学者,前几天刚刚接触多线程这个东西,有了些微微的理解想写下来(不对的地方请多多包涵并指教哈). 多线程怎么写代码就不说了,一搜一大堆.说说多线程我认为最难搞的地方,就是来回释放锁以及 ...
- 可持久化treap(FHQ treap)
FHQ treap 的整理 treap = tree + heap,即同时满足二叉搜索树和堆的性质. 为了使树尽可能的保证两边的大小平衡,所以有一个key值,使他满足堆得性质,来维护树的平衡,key值 ...
- BZOJ 4027: [HEOI2015]兔子与樱花
贪心 #include<cstdio> #include<algorithm> using namespace std; int cnt,n,m,F[2000005],c[20 ...
- Windows清理打印池的方法
另存为bat运行 @echo off title 快速清除打印队列 echo. echo 停止打印机服务 net stop spooler>nul echo. del /q /f %wind ...