vue2.0中的计算属性
计算属性是一个很邪门的东西,只要在它的函数里引用了data中的某个属性,当这个属性发生变化的时候,函数仿佛可以嗅探到这个变化,并自动重新执行。
View Code
上代码会源源不断的打印出a的值。如果希望b依赖data中的x而变化,只需要保证b函数中有this.x即可。如果函数中没有出现data中的属性,那么无论data中的属性怎么变,b对应的函数一次也不会执行。
Vue是怎么知道计算属性在函数中引用了哪个data属性?这个函数又是怎么知道data属性变了,而且只关心它内部引用的那个属性,别的都不管?官方文档是这么说的:
我们简单模拟实现一个计算属性:a变化时,b自动跟着变化。
var obj = {a:0,
b:function(){
var a = this.a;
return a + 1;
}
}
由于涉及到Vue的双向绑定的原理,如果你对此不熟,最好先看看《Vue.js双向绑定的实现原理》
程序执行过程:
1、首先b属性会被处理为存取器属性,访问b就会触发其get函数;
2、处理计算属性a时,会执行a的函数,从而会执行this.b,于是触发b的get函数;
3、b的get函数会添加b属性的依赖项,而刚才在处理计算属性过程中,a已经作为依赖项被传给了一个全局变量,b的get函数会检测到这个全局变量,并将其添加到自身的订阅者列表中;
4、对b赋予新的值时,会触发其set函数,set函数中会遍历执行订阅者,a的值就是在这个时候更新的。
再看代码:
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Two-way-data-binding</title>
</head>
<body>
<script>
var Dep = null;
function defineReactive(obj, key, val) {
var deps = [];
Object.defineProperty(obj, key, {
get: function () {
if (Dep) {
deps.push(Dep);
}
return val;
},
set: function (newval) {
val = newval;
deps.forEach(func => func());
}
})
}
function defineComputed(obj, key, func) {
func = func.bind(obj);
var value;
Dep = function () {
value = func();
};
value = func();
Dep = null;
Object.defineProperty(obj, key, {
get: function () {
return value;
}
})
}
var obj = {};
defineReactive(obj, 'a', 0);
defineComputed(obj, 'b', function () {
var a = this.a;
return a + 1;
})
</script>
</body>
</html>
View Code
通过对存取器属性、闭包和观察者模式的综合运用,Vue巧妙的实现了计算属性。可以看出,Vue响应式系统的核心理念是“依赖”,DOM节点之所以随数据而变化,是因为节点依赖于数据,计算属性之所以随数据而变化,是因为计算属性依赖于数据,做好响应式的关键就在于处理好依赖关系。
参考文章:https://skyronic.com/blog/vuejs-internals-computed-properties
以上是 vue2.0中的计算属性 的全部内容, 来源链接: utcz.com/z/375792.html