Vue 监听器和计算属性到底有什么不同?
各自的适用场景
计算属性临时快照
官方文档对于计算属性提到了一个重要的点子——“临时快照”(可能就是前面说的计算属性缓存),每当源状态发生变化时,就会创建一个新的快照。
有时候创建快照是没有意义的,对于间隔时间很短的源数据修改,比如输入框输入时页面上的一些变化。输入第一个字符到第二个字符之间的间隔时间,字符有长有短,每一次都要创建“临时快照”,这样是没有意义的,反而可能增加开销。
计算属性除了可以用于复杂的模板取值计算(普通函数也可以做,也不是它的特性),还可以计算一次而在页面上多次使用(这是计算属性的“临时快照”的优势)。
监听器的副作用
因此,上面说到的情况就更加适合用监听器来做,监听器不创建“临时快照”。监听器更适用于官方文档说的场景:“我们需要在状态变化时执行一些‘副作用’:例如更改 DOM,或是根据异步操作的结果去修改另一处的状态”。
监听器的副作用就是被监测的数据源发生变化才被触发,而不能被其他数据源发生变化而受到影响。具体往下看,就是我说的监听器单一性。
深入思考两者区别
计算属性由于在计算过程中依赖了很多响应式数据,一旦某一个响应式数据发生变化,那么整个计算属性都将重新计算。我就自以为计算属性有共享性。
虽然监听器也可以依赖于很多响应式数据,但是监听器只负责一个数据源,而被依赖的其他响应式数据一旦发生变化,都无法触发这个监听器,即监听器的单一性。
监听器:单一性
Talk is cheap. Show me the code.
定义两个输入框需要绑定的响应式数据 input
、copyInput
,监听器只负责监听 input,当监听器被触发时,新的值将赋值给 input,并且 input 也拼接给 copyInput(这里为了让两个产生联系而设计的无脑代码):
let input = ref("");
let copyInput = ref("");
watch(input, (newVal, oldVal) => {
input.value = newVal;
copyInput.value += input.value;
console.log("input value has changed.");
});
输入框绑定响应式数据,页面展示 copyInput:
<div class="demo1">
<div>CopyInput Value: {{ copyInput }}</div>
<div>
<span>Input: </span>
<input v-model="input" />
</div>
<div>
<span>CopyInput: </span>
<input v-model="copyInput" />
</div>
</div>
第一个输入框内(即绑定 input 的输入框)输入三次,监听器被触发 3 次,当第二个输入框的数据发生变化时,控制台不打印,也就是说,监听器里面被依赖的数据没有因为改变而被触发。
计算属性:共享性
计算属性里面被依赖的其中一个响应式数据发生了变化,整个计算属性都将被重新计算。那么,计算属性是否和上面提到的监听器一样呢?
let input = ref("");
let copyInput = ref("");
const result = computed(() => {
console.log("computed has changed.");
return (copyInput.value += input.value);
});
<div class="demo2">
<div>CopyInput Value Result: {{ result }}</div>
<div>
<span>Input: </span>
<input v-model="input" />
</div>
<div>
<span>CopyInput: </span>
<input v-model="copyInput" />
</div>
</div>
不管我改哪一个,只要是被计算属性依赖的数据源发生改变,这个计算属性都被触发,即共享性:
总结
(1)计算属性适合数据源发生变化间隔长,且页面使用它的次数多的情况;监听器适合数据源发生变化间隔短,或有异步操作,或有副作用的情况。
(2)如果不想其他响应式数据发生变化而导致被监测的源数据发生变化,那么就使用监听器。如果其他响应式数据发生变化,而被监测的源数据也一同发生变化,那么就使用计算属性。
声明
文章中所说的计算属性具有共享性和监听器具有单一性是为了方便理解他们之间的不同,博主擅自给的定义,可能存在不严谨的地方。
- 计算属性具有共享性:指的是计算属性里面的被依赖的响应式数据只要有一个发生变化,整一个计算属性都重新计算,牵一发而动全身。
- 监听器具有单一性:指的是监听器只负责它监听的那个数据源,如果发生变化,才会被触发,如果里面被依赖的其他数据源发生变化时,这个监听器不会被触发。
以上证明了我所阐述的观点,如果你有收货,请给我点个赞+收藏吧!
Vue 监听器和计算属性到底有什么不同?的更多相关文章
- vue监听器watch & 计算属性computed
侦听器watch vue中watch是用来监听vue实例中的数据变化 watch监听时有几个属性: handle:其值是一个回调函数,就是监听对象对话的时候需要执行的函数 deep:其值true 或者 ...
- Vue的computed计算属性是如何实现的
一个开始 有如下代码,full是一个计算属性,开始,他的值是'hello world',1s后,msg变成了‘I like’, full的值同步变成了'I like world';其原理解析来看一下. ...
- Vue学习之vue中的计算属性和侦听器
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Vue(基础三)_监听器与计算属性
一.前言 本文主要涉及: 1.watch()监听单个属性 2.computed可以监听多个属性 3.点击li标签切换音乐案例 二.主要内容 1.watch()监听器(监听单一数据) (1)监听 ...
- Vue中的计算属性和监听器(computed 与 watch)
react中数据是单向绑定的,而vue中数据是双向绑定的.为什么? 在react中,主要是通过setState 去改变state的值:而在vue中,会自动的触发set 与get 改变属性的值. 在vu ...
- Vue基础之计算属性
适用场景 设想一个场景,你需要得到一个复杂运算/逻辑的返回值,利用模板内的表达又过长且难以阅读和维护,这时计算属性就可以很好的解决你的问题.看下面的例子: <!DOCTYPE html> ...
- 关于vue.js的计算属性练习代码
参照官网联系如下: <!DOCTYPE html><html lang="en"><head> <meta charset="U ...
- Vue 过滤器与计算属性
过滤器 V1.x 版本 过滤器基础 过滤器是一个通过输入数据,能够及时对数据进行处理并返回一个数据结果的简单函数.Vue有很多很便利的过滤器,可以参考官方文档,http://cn.vuejs.org/ ...
- vue学习笔记 计算属性(四)
计算属性就是vue实例里的computed属性,对应一个对象,里面可以放各种方法,方法的作用就是可以生成和数据变量对应的计算后的变量,跟数据相关的复杂逻辑变量,都可以使用计算属性实现,computed ...
随机推荐
- vue虚拟dom和diff算法
vue的虚拟dom和diff算法 1.虚拟dom 虚拟dom,我的理解就是通过js对象的方式来具体化每一个节点,把dom树上面的每个节点都变为对象里的一个元素,元素的子元素变为子节点,节点上面的cla ...
- 《阿里云天池大赛赛题解析》——O2O优惠卷预测
赛事链接:https://tianchi.aliyun.com/competition/entrance/231593/introduction?spm=5176.12281925.0.0.7e157 ...
- WPF开发随笔收录-DataAnnotations实现数据校验(MVVM架构下)
一.前言 在自己的项目中挺多地方需要涉及到数据验证的,初期的实现方式都是通过点击确定后再逐个验证数据是否符合要求,但这种方式会让后台代码变得很多很乱.于是就开始在网上需求好的解决方式,刚好看到了一个大 ...
- 机械硬盘和ssd固态硬盘的原理对比分析
固态硬盘和机械硬盘的区别 机械硬盘 磁头是不是直接和盘片接触的呢 磁盘中有几个盘片 机械硬盘的工作原理 固态硬盘的寻址方式 SMR叠瓦式真的比PMR优秀吗 固态硬盘 主控芯片 闪存颗粒 缓存单元 固态 ...
- 记一次排查线上MySQL死锁过程,不能只会curd,还要知道加锁原理
昨晚我正在床上睡得着着的,突然来了一条短信. 啥,线上MySQL死锁了,我赶紧登录线上系统,查看业务日志. 能清楚看到是这条insert语句发生了死锁. MySQL如果检测到两个事务发生了死锁,会回滚 ...
- 坐标PCB公司,想做实时数仓、推生产线看板,和Tapdata Cloud的偶遇来得就是这么凑巧
Tapdata Cloud 是一款很有「前途」的产品.--Tapdata Cloud 用户 | 一线DBA@某PCB全球百强企业 从首次提出这一概念起,已经 10 年过去了,"工业互 ...
- Linux操作系统(7):rpm包管理和yum软件包在线管理
一.rpm 包的管理 介绍:一种用于互联网下载包的打包及安装工具,它包含在某些 Linux 分发版中.它生成具有.RPM 扩展名的文件.RPM 是 RedHat Package Manager(Red ...
- putchar与getchar
#include <stdio.h>#include <stdlib.h>void myputs(char*p) //此处的*号是标志,标志这P是一个指针{ if(p==NUL ...
- java的方法(类似与C语言函数)
package www.nihao; import java.util.Scanner; public class demo02 { public static void main(String[] ...
- APISpace 疫情地区校验API接口 免费好用
从2019年疫情开始爆发到现在,我们去到某个地方都会提心吊胆的,很怕一不小心就染上了这个病毒.在去到某个地方之前,我们提前查看到它的一个疫情等级,同时做好防护再出门我们心里也会有底一些.所以疫情地区校 ...