Vue.js 计算属性的秘密
计算属性是一个很邪门的东西,只要在它的函数里引用了 data 中的某个属性,当这个属性发生变化时,函数仿佛可以嗅探到这个变化,并自动重新执行。
上述代码会源源不断的打印出 b 的值。如果希望 a 依赖 data 中的 x 而变化,只需保证 a 函数中有 this.x 即可。如果函数中没有出现 data 中的属性,那么无论 data 中的属性怎么变,a 对应的函数一次也不会执行。
Vue 怎么知道计算属性在函数中引用了哪个 data 属性?这个函数又是怎么知道 data 属性变了,而且只关心它内部引用的那个属性,别的都不管?
官方文档对计算属性的描述是:
文档的描述让我的困惑更加困惑,还有这种操作?这特么是怎么做到的?
Google 了一把,看了一篇三哥的博文(见文末),豁然开朗。
由于涉及 Vue 的响应式绑定的原理,如果你对此不熟,最好先看看这篇文章
少啰嗦,先看过程:
1. 首先 b 属性会被处理为存取器属性,访问 b 就会触发其 get 函数
2. 处理计算属性 a 时,会执行 a 的函数,从而会执行 this.b,于是触发 b 的 get 函数
3. b 的 get 函数会添加 b 属性的依赖项,而刚才在处理计算属性过程中,a 已经作为依赖项被传给了一个全局变量,b 的 get 函数会检测到这个全局变量,并将其添加到自身的订阅者列表中
4. 对 b 赋予新的值时,会触发其 set 函数,set 函数中会遍历执行订阅者,a 的值就是在这个时候更新的
再看代码:
(注:图中数字仅作思路引导,并非与前文过程描述对应)
测试一下,完美打印出 1, 2, 3, 4
console.log(obj.b)
obj.a += 1;
console.log(obj.b);
obj.a += 1;
console.log(obj.b);
obj.a += 1;
console.log(obj.b);
通过对存取器属性、闭包和观察者模式的综合运用,Vue 巧妙的实现了计算属性。现在再看官方文档描述,是不是更通透了呢。
可以看出,Vue 响应式系统的核心理念是“依赖”,DOM 节点之所以随数据而变化,是因为节点依赖于数据,计算属性之所以随数据而变化,是因为计算属性依赖于数据。做好响应式的关键就在于处理好依赖关系。
参考文章:https://skyronic.com/blog/vuejs-internals-computed-properties
Vue.js 计算属性的秘密的更多相关文章
- Vue.js 计算属性是什么
Vue.js 计算属性是什么 一.总结 一句话总结: 模板 表达式 维护 在模板中表达式非常便利,但是它们实际上只用于简单的操作.模板是为了描述视图的结构.在模板中放入太多的逻辑会让模板过重且难以维护 ...
- Vue.js 计算属性(computed)
Vue.js 计算属性(computed) 如果在模板中使用一些复杂的表达式,会让模板显得过于繁重,且后期难以维护.对此,vue.js 提供了计算属性(computed),你可以把这些复杂的表达式写到 ...
- Vue.js 计算属性
Vue.js 计算属性 使用计算属性的实例: <!DOCTYPE html> <html> <head> <meta cahrset="utf-8& ...
- vue.js计算属性 vs methods
计算属性:Vue.js 模板内的表达式非常便利,但是缺点就是只能用于简单的运算,如果模板中有太多的逻辑运算会让模板不堪重负且难以维护.恰恰计算属性可以处理复杂的逻辑运算,也就是说对于任何复杂逻辑你都应 ...
- Vue.js 计算属性computed和methods的区别
在vue.js中,有methods和computed两种方式来动态当作方法来用的 如下: 两种方式在这种情况下的结果是一样的 写法上的区别是computed计算属性的方式在用属性时不用加(),而met ...
- 一起学Vue之计算属性和侦听器
概述 在Vue开发中,模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的.在模板中放入太多的逻辑会让模板过重且难以维护.当你想要在模板中多次引用相同表达式时,就会更加难以处理.所以,对于任何复 ...
- vue的计算属性computed和监听器watch
<template> <div> this is A.vue <br> <!--计算属性--> <label for="msg" ...
- vue的计算属性
在模板中写入过多的逻辑使模板过重且难以维护.因此有了计算属性(computed)的产生. 你可以像绑定普通属性一样在模板中绑定计算属性,vue知道计算属性中的函数依赖data中的数据.所以当data中 ...
- vue中计算属性的get与set方法
计算属性get set方法 在vue的计算属性中,所定义的都是属性,可以直接调用 正常情况下,计算属性中的每一个属性对应的都是一个对象,对象中包括了set方法与get方法 computed:{ ful ...
随机推荐
- Dubbo高级特性实践-泛化调用
引言 当后端Java服务用Dubbo协议作为RPC方案的基础,但部分消费方是前端Restful的PHP服务,不能直接调用,于是在中间架设了Router服务提供统一的基于HTTP的后端调用入口. 而Ro ...
- jQuery UI 日期选择器(Datepicker)
设置JqueryUI DatePicker默认语言为中文 <!doctype html><html lang="en"> <head> < ...
- 闭包JS
一句话概括的话:闭包就是一个函数,捕获作用域内的外部绑定. 官方的定义:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因为这些变量也称为该表达式的一部分. 自由变量和闭包的关系:自 ...
- Merge使用
Role r = new Role(); r.setName("TEST"); r.setDescription("123"); r.setLevel(2); ...
- python数据结构链表之单向链表
单向链表 单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域.这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值. 表元素域ele ...
- (转) Eclipse Maven 编译错误 Dynamic Web Module 3.1 requires Java 1.7 or newer 解决方案
场景:在导入Maven项目时候遇到如下错误. 1 问题描述及解决 Eclipse Maven 开发一个 jee 项目时,编译时遇到以下错误:Description Resource Path Loca ...
- 第一个asp.net实例——生日邀请以及回函
22回校后,看了论文游了西湖,今天开始接触asp.net,从图书馆选了两本书:<精通ASP.NET 4.5 (第五版)>,<ASP.NET全能速查手册>.一本练手细看,一本翻查 ...
- Linux文件系统,ntfs分区显示只读文件系统,提示超级快损坏
背景:某天当我打开自己的设备,突然发现ntfs分区无法写入任何文件,提示为只读文件系统,具体现象如下: 修复过程:排除权限问题,使用fsck进行修复无果后,使用e2fsck进行修复 显示超级快损坏,这 ...
- Chrome调试工具developer tool技巧
Chrome这个浏览器赞的不能再赞了,给前端的开发调试工作带来了极大的效率提升. Chrome的简洁.快速吸引了无数人,它的启动速度.页面解析速度都很快,同时得益于Google V8的快速,Javas ...
- DDD理论学习系列(12)-- 仓储
DDD理论学习系列--案例及目录 1. 引言 DDD中Repository这个单词,主要有两种翻译:资源库和仓储,本文取仓储之译. 说到仓储,我们肯定就想到了仓库,仓库一般用来存放货物,而仓库一般由仓 ...