计算属性是一个很邪门的东西,只要在它的函数里引用了data中的某个属性,当这个属性发生变化的时候,函数仿佛可以嗅探到这个变化,并自动重新执行。


上代码会源源不断的打印出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>

通过对存取器属性、闭包和观察者模式的综合运用,Vue巧妙的实现了计算属性。可以看出,Vue响应式系统的核心理念是“依赖”,DOM节点之所以随数据而变化,是因为节点依赖于数据,计算属性之所以随数据而变化,是因为计算属性依赖于数据,做好响应式的关键就在于处理好依赖关系。

参考文章:https://skyronic.com/blog/vuejs-internals-computed-properties

vue2.0中的计算属性的更多相关文章

  1. vue2.x中使用计算属性巧妙的实现多选框的“全选”

    接下来我会以一个购物车的例子,来演示如果借助计算属性,精巧的实现多选框的全选功能.当然,有全选,自然对应的也还有取消全选. 以下这张gif图,就是最终的实现效果: 第一步,针对购物车每一个商品进行设置 ...

  2. Vue2.0 中,“渐进式框架”和“自底向上增量开发的设计”这两个概念是什么?(转)

    https://www.zhihu.com/question/51907207?rf=55052497 徐飞 在我看来,渐进式代表的含义是:主张最少. 每个框架都不可避免会有自己的一些特点,从而会对使 ...

  3. Vue - 在v-repeat中使用计算属性

    1.从后端获取JSON数据集合后,对单条数据应用计算属性,在Vue.js 0.12版本之前可以在v-repeat所在元素上使用v-component指令 在Vue.js 0.12版本之后使用自定义元素 ...

  4. vue2.0动态绑定图片src属性值初始化时报错

    在vue2.0中,经常会使用类似这样的语法 v-bind:src = " imgUrl "(缩写 :src = " imgUrl "),看一个案例 <te ...

  5. Vue2.0中的transition组件

    组件的过度 Vue1.0中transition做为标签的行内属性被vue支持.但在Vue2.0中.Vue放弃了旧属性的支持并提供了transition组件,transition做为标签被使用. 使用t ...

  6. Vue中的计算属性与$watch

    计算属性:在模板中绑定表达式是非常便利的,但是他们实际上只用于简单的操作.模板是为了描述视图的结构.在模板中放入太多的逻辑会让模板过重且难以维护.这就是为什么vue.js将绑定表达式限制为一个表达式. ...

  7. vue2.0中使用less

    第一部分:Less语言 与上一篇<vue2.0中使用sass>介绍的Sass语言一样,Less语言也是一种CSS的扩展语言,增加了变量.混合(minin).函数等功能,让CSS更易维护.方 ...

  8. vue2.0中使用sass

    第一部分:Sass语言 Sass是一种强大的css扩展语言(css本身并不是一门语言),它允许你使用变量.嵌套规则.mixins.导入等css没有但开发语言(如Java.C#.Ruby等)有的一些特性 ...

  9. Vue2.0中的路由配置

    Vue2.0较Vue1.0,路由有了较大改变.看一下Vue2.0中的路由如何配置: 步骤一: 在main.js文件中引入相关模块以及组件及实例化vue对象配置选项路由及渲染App组件 默认设置如下: ...

随机推荐

  1. 南昌网络赛 Distance on the tree 主席树+树剖 (给一颗树,m次查询ui->vi这条链中边权小于等于ki的边数。)

    https://nanti.jisuanke.com/t/38229 题目: 给一颗树,m次查询ui->vi这条链中边权小于等于ki的边数. #include <bits/stdc++.h ...

  2. order by关键字

    作用:用于对查询结果进行排序 select * from emp where deptno = 20 order by sal 1.如何决定升序还是降序 默认排序:升序:select * from e ...

  3. html5: 复制到剪贴板 clipboard.js

    1.使用clipboard.min.js工具,引用此js 注意事项: IOS微信网页开发中,若使用此工具来开发复制功能,则需要在超链接/按钮上新增 onclick=" " 2.cl ...

  4. 编写一个算法,将非负的十进制整数转换为其他进制的数输出,10及其以上的数字从‘A’开始的字母表示

    编写一个算法,将非负的十进制整数转换为其他进制的数输出,10及其以上的数字从‘A’开始的字母表示. 要求: 1) 采用顺序栈实现算法: 2)从键盘输入一个十进制的数,输出相应的八进制数和十六进制数. ...

  5. (转)基于OpenStack构建企业私有云(1)实验环境准备

    原文:https://www.unixhot.com/article/407 https://www.cnblogs.com/kevingrace/p/5707003.html-----完整部署Cen ...

  6. C#的托管和非托管的简单理解

    应该说“托管”一词是和.net概念一起出生的, 我们都知道以前的开发工具无论是Delphi.VB编译出的dll或exe文件都是二进制文件, 可以被操作系统直接识别.而微软为了和JAVA火拼,实现跨平台 ...

  7. spingAOP在springMVC中的使用(我用在拦截controller中的方法。主要用于登录控制)

    首先截取了网上的一张配置execution的图片 我在项目中关于aop的配置:如果拦截controller的方法,需要在spring-mvc.xml文件中加入(如果在spring.xml中加入则无法拦 ...

  8. 公司Git实用记录

    一.git命令名词解释 1.添加/跟踪/暂存:添加到本地索引 git add 文件名 2.提交:提交到本地仓库 git commit -m '注释' 3.推送:将提交到本地仓库的所有更新提交到服务器 ...

  9. Java 动态代理机制分析及扩展--转

    http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/#icomments http://www.ibm.com/developerworks/c ...

  10. c# 中 event 和 delegate 的区别

    event 是一种特殊的delegate. 1)event 在本类(派生类也不行)之外不能触发.(如果是public的在类外或protected的在派生类中可以使用 += 或 -=, 但不能调用该ev ...