Vue 计算属性与侦听器

这一节我们一起学习 vue 中的计算属性(computed properties)和侦听器(watch)。

在之前,我们学习过 vue 表达式插值:

<div id="example">{{ message.split('').reverse().join('') }}
</div>

如果在模板中放入太多的逻辑会让模板过重且难以维护。我们可以把方法写在事件处理函数里面,并且在构造器内部通过 this 调用。
<!-- more -->
Html 代码:

<h1>{{ this.reversedMessageMethod() }}</h1>

JS 代码:

methods: {reversedMessageMethod() {return this.message.split('').reverse().join('');},
},
这里要提醒一下,我们不可以把事件处理函数写成箭头函数,因为这里的 this 需要指向 vue 实例。

一、过滤器

其实,模板中的处理逻辑是不适合放在事件处理函数里的,即使可以这么做。事件处理函数应该专注于处理事件,我们应该让它变得纯粹。在 vue 中, 允许我们自定义过滤器(filters),可被用于一些常见的文本格式化。

过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部,由 | 符号指示,我们看看怎么用:

<template><div class='hello'><h1>{{ message.split('').reverse().join('') }}</h1><!-- add this --><h1>{{ message | reverseString }}</h1></div>
</template><script>
export default {name: 'HelloWorld',data() {return {message: 'Welcome to Your Vue.js App',};},// add this  filters: {reverseString(val) {let value = val;if (!value) return '';value = value.split('').reverse().join('');return value;},},
};
</script>

代码增多了,但是整体的语义化却更好。从 filters 的用法我们可以看出:

  • 它是一对一的,对单个数据进行过滤,可以进行传参
  • 适用于同方法、不同参数的情况

所以,filters 的缺点就很明显了:如果要计算结合多个数据不同变化的情况,过滤器就无法适用了。这就要用到我们下面提到的计算属性了。

二、计算属性

vue 中,也为我们提供了computed 这个选项来处理数据,我们称它为计算属性。当逻辑复杂的时候,我们就应当使用 computed 计算属性了。计算属性使用起来非常简单,我们还是用上面的例子,使用计算属性来修改模板中的逻辑:

<template><div class='hello'><h1>{{ message.split('').reverse().join('') }}</h1><h1>{{ message | reverseString }}</h1><h1>{{ this.reversedMessageMethod() }}</h1><!-- add this --><h1>{{ reversedMessage }}</h1></div>
</template><script>
export default {name: 'HelloWorld',data() {return {message: 'Welcome to Your Vue.js App',};},filters: {reverseString(val) {let value = val;if (!value) return '';value = value.split('').reverse().join('');return value;},},// add thiscomputed: {reversedMessage() {return this.message.split('').reverse().join('');},},methods: {reversedMessageMethod() {return this.message.split('').reverse().join('');},},
};
</script>

method 选项的使用非常相似。我们可以像绑定普通属性一样在模板中绑定计算属性。

这两种方式的最终结果确实是完全相同的。然而,不同的是:计算属性是基于它们的依赖进行缓存的。什么意思呢?

只在相关依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数;而当数据有变化时,只要有一个数据发生变化,则会重新计算,来更新视图的改变。相比之下,每当触发重新渲染时,调用 methods 中的方法将总会再次执行函数。

我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 Agetter

我们来看看计算属性的具体应用场景:

1、微博发文

发微博的时候,有字数限制。在我们输入文字的时候,输入框会计算我们还可以输入多少字:

<template><div><textarea v-model='content' :maxlength='totalcount'></textarea><p>你还可以输入{{reduceCount}}字</p></div>
</template><script>
export default {data() {return {totalcount: 200, // 总共只给输入200字content: '',};},computed: {reduceCount() {return this.totalcount - this.content.length;},},
};
</script>

通过一直监听输入的字符的长度来触发 computed 里的 reduceCount 方法,重新计算,然后返回给视图,让视图作出相应的变化。接下来我们再看一个例子。

2、足球比赛

这个例子是一个足球比赛的结果播报板,我们先看看最终的效果,再看代码:

效果 :

match

代码:

<template><div><h1>比赛时间:{{time}}s</h1><h2>直播播报:{{result}}</h2><div class='team'><div><p>中国队进球数:{{team.china}}</p><button @click='team.china++'>点击中国队进一球</button></div><div><p>韩国队进球数:{{team.korea}}</p><button @click='team.korea++'>点击韩国队进一球</button></div></div></div>
</template><script>
export default {created() {const time = setInterval(() => {this.time = this.time + 1;if (this.time === 90) {clearInterval(time);}}, 1000);},data() {return {time: 0,team: {china: 0,korea: 0,},};},computed: {result() {if (this.time < 90) {if (this.team.china > this.team.korea) {return '中国队领先';} else if (this.team.china < this.team.korea) {return '韩国队领先';}return '双方僵持';}if (this.team.china > this.team.korea) {return '中国队赢';} else if (this.team.china < this.team.korea) {return '韩国队赢';}return '平局';},},
};
</script><style scoped>
.team {display: flex;justify-content: center;
}
button {padding: 15px 60px;outline: none;background-color: #27ae60;display: block;font-size: 1rem;color: #fff;margin: 10px;
}
</style>

通过上面的例子,我们就可以很清楚 computed 的作用了:观察一个或者多个数据,只要依赖的数据发生变化的时,这个函数就会重新计算。这样我们就可以通过观察所有数据来维护一个状态,也就是所谓的返回一个状态值。

三、侦听器

虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。

computed watch 都可以做同一件事,两个选项都是对数据进行时时监听。但是它们也有不同:

  • computed 多数据变动进行监听,返回一个状态,维护一个状态
  • watch 是对一个数据监听,在数据变化时,会返回两个值,一个是 value (当前值),二是 oldvalue 是变化前的值

我们也可以用 watch 选项来改造上面的足球比赛的例子,添加一个 watch 选项:

<script>
export default {created() {const time = setInterval(() => {this.time = this.time + 1;if (this.time === 90) {clearInterval(time);}}, 1000);},data() {return {time: 0,team: {china: 0,korea: 0,},};},// add this  watch: {time(value, oldval) { // eslint-disable-lineif (value < 90) {if (this.team.china > this.team.korea) {this.result = '中国队领先';} else if (this.team.china < this.team.korea) {this.result = '韩国队领先';} else {this.result = '双方僵持';}} else if (this.team.china > this.team.korea) {this.result = '中国队赢';} else if (this.team.china < this.team.korea) {this.result = '韩国队赢';} else {this.result = '平局';}},team(value, oldval) { // eslint-disable-lineif (this.time < 90) {if (value.china > value.korea) {this.result = '中国队领先';} else if (value.china < value.korea) {this.result = '韩国队领先';} else {this.result = '双方僵持';}} else if (value.china > value.korea) {this.result = '中国队赢';} else if (value.china < value.korea) {this.result = '韩国队赢';} else {this.result = '平局';}},},
};
</script>

可以看出跟使用 computed 选项是差不多一致的。那 watch 有什么应用场景呢?

有一个很常见的场景:图片的预加载。当图片数量比较大的时候,为了保证页面图片都加载出来的时候,才把主页面给显示出来,然后再进行一些 ajax 请求,或者逻辑操作,这个时候用 computed 就无法实现了,只能用 watch ,看看代码:

<template><div v-show='show'><img src='https://img.alicdn.com/simba/img/TB14sYVQXXXXXc1XXXXSutbFXXX.jpg' alt><img src='//img.alicdn.com/tfs/TB1iZ6EQXXXXXcsXFXXXXXXXXXX-520-280.jpg_q90_.webp' alt><img src='https://img.alicdn.com/simba/img/TB1C0dOPXXXXXarapXXSutbFXXX.jpg' alt><img src='//img.alicdn.com/tfs/TB1iZ6EQXXXXXcsXFXXXXXXXXXX-520-280.jpg_q90_.webp' alt></div>
</template><script>
export default {data() {return {count: 0,show: false,};},mounted() {const imgs = document.querySelectorAll('img');console.log(imgs); // eslint-disable-lineArray.from(imgs).forEach((item) => {const img = new Image();img.onload = () => {this.count = this.count + 1;};img.src = item.getAttribute('src');});},watch: {count(val, oldval) { // eslint-disable-lineif (val === 4) {this.show = true;alert('加载完毕'); // eslint-disable-line// 然后可以对后台发送一些ajax操作}},},
};
</script>

我们可以发现等四张图片都加载完毕的时候页面才显示出来。所以当我们想要在数据变化响应时,执行异步操作或开销较大的操作,就需要使用 watch 了。

四、总结

过滤器 filter :

  • 一对一,对单个数据进行过滤,可以进行传参
  • 适用于同方法、不同参数的情况
  • 不适用于结合多个数据变化的情况

计算属性 computed :

  • 监听一个或者多个数据来维护返回一个状态值
  • 只在相关依赖发生改变时它们才会重新求值

侦听器 watch :

  • 对一个数据监听
  • 在数据变化时,会返回两个值,一个是 value (当前值),二是 oldvalue 是变化前的值
注:本节内容的 demo 均来自 混元霹雳手,感谢作者!

本节内容代码:https://github.com/IDeepspace...

欢迎关注我的博客:https://togoblog.cn/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/537014.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

程序员到底要不要重复造轮子?

分享一波:程序员赚外快-必看的巅峰干货 关于这个话题&#xff0c;现在这里阐述立场&#xff1a;就公司工作而言&#xff0c;不建议重复造轮子。就个人技术而言&#xff0c;强烈建议造轮子&#xff01; 程序员圈子里流行这么一句话&#xff1a;“不要重复造轮子”。它的原文是…

1582年日历怎么了_【知乎周边】知乎2020年日历开箱+测评

感谢 刘看山 刘看山福利社 知一声 这边知乎朋友赠送的礼物&#xff0c;这边拿到了新的一年2020年知乎的日历。随日历还赠送了一年的盐选会员体验卡&#xff0c;这个福利很特别哈。打开盒子&#xff0c;里面是厚厚的但是却不是很大的一个正方体。侧面写有“有问题的日历”日历内…

JDK8那些惊为天人的新特性

分享一波:程序员赚外快-必看的巅峰干货 介绍 随着java的发展&#xff0c;越来越多的企业开始使用 java8 版本。Java8 是自 java5之后最重要的版本&#xff0c;这个版本包含语言、编译器、库、工具、JVM等方面的十多个新特性。本次课程将着重学习其中的一些重点特性。 Jdk8新…

【数据结构和算法05】 红-黑树(转发)

2019独角兽企业重金招聘Python工程师标准>>> 【数据结构和算法05】 红-黑树&#xff08;看完包懂~&#xff09; 置顶 2016年04月13日 15:50:25 eson_15 阅读数&#xff1a;52681 标签&#xff1a; java数据结构算法红黑树 更多 个人分类&#xff1a; ● 结构算法---…

数据结构与算法——二叉树、堆、优先队列

*************************************优雅的分割线 ********************************** 分享一波:程序员赚外快-必看的巅峰干货 七、树 7.1 树 7.1.1 树的定义 树是我们计算机中非常重要的一种数据结构&#xff0c;同时使用树这种数据结构&#xff0c;可以描述现实生活…

继牛津大学后,加大伯克利分校等多家美国高校终止与华为合作

文&#xff0f;AI财经社 唐煜编&#xff0f;嵇国华据 Nature News 报道&#xff0c;在美国相关部门的压力之下&#xff0c;加州大学伯克利分校&#xff08;UC Berkeley&#xff09;近日宣布不再与华为签署新的研究合作&#xff1b;德州大学奥斯丁分校也正在审查自身与华为的关系…

为什么varchar字段长度最好是2的n次方-1

*************************************优雅的分割线 ********************************** 分享一波:程序员赚外快-必看的巅峰干货 计算机是二进制计算的&#xff0c;1 bytes 8 bit ,一个字节最多可以代表的数据长度是2的8次方 11111111 在计算机中也就是-128到127。 而var…

Python之celery的简介与使用

celery的简介 celery是一个基于分布式消息传输的异步任务队列&#xff0c;它专注于实时处理&#xff0c;同时也支持任务调度。它的执行单元为任务&#xff08;task&#xff09;&#xff0c;利用多线程&#xff0c;如Eventlet&#xff0c;gevent等&#xff0c;它们能被并发地执行…

不使用比较运算符如何比较两个数的大小

分享一波:程序员赚外快-必看的巅峰干货 前言 今天在水群的过程中看到有位群员谈论到这个话题&#xff0c;是他找工作过程中某家公司的面试题&#xff08;到底是哪家公司才会出这种没营养的题目刁难别人&#xff09;&#xff0c;有点兴趣&#xff0c;就开始写了。 开搞 想了一…

java占位符填充_Java使用freemark生成word

1、制作模板先用office word做一个模板word文档&#xff0c;${usrName}、${nowDate}占位符 可以使用 office 或者 wps 先创建一个模板表格 &#xff08;替换$部分可以在 模板格式改变之后 在替换xml 格式改了后有些原本的字符会分开&#xff09;2、用office word将模板word另存…

Java中如何使用非阻塞异步编程——CompletableFuture

分享一波:程序员赚外快-必看的巅峰干货 对于Node开发者来说&#xff0c;非阻塞异步编程是他们引以为傲的地方。而在JDK8中&#xff0c;也引入了非阻塞异步编程的概念。所谓非阻塞异步编程&#xff0c;就是一种不需要等待返回结果的多线程的回调方法的封装。使用非阻塞异步编程…

城市运行一网统管_【宣传活动】持续开展城市运行“一网统管”建设宣传活动...

为进一步推进本镇城市运行“一网统管”建设工作&#xff0c;提高城市治理能力和治理水平&#xff0c;提升社会各界的知晓度和参与度&#xff0c;激发职能部门人员、党员、群众参与“一网统管”工作的热情。9月10日&#xff0c;镇网格中心于福泉居委会议室开展“推进城市运行‘一…

Java如何只使用位运算实现加减乘除

分享一波:程序员赚外快-必看的巅峰干货 前言 接前面一篇博客&#xff0c;这又是某个公司的奇葩面试题&#xff08;都说了到底是哪家公司才会出这种没营养的面试题&#xff09;。不过吐槽归吐槽&#xff0c;这个题目还是有点学问的&#xff0c;比前面那个 不使用比较运算符如何…

pmc订单表格_复工了,读一则“如何提升订单准交率和生产效率”的真实故事

故事发生在中国南方小镇上一个做办公家具的公司……家具公司创建于1995年&#xff0c;是一家集研发、生产、销售、服务为一体的现代办公家具、酒店家具制造企业。主要产品有实木班台系列、会议台系列、职员桌系列、屏风系列、沙发系列、办公座椅、酒店家具系列。在省外还有两个…

GET和POST请求到底有什么区别?

分享一波:程序员赚外快-必看的巅峰干货 看到这个标题&#xff0c;想必大部分人都已经想关掉这篇博客了。先别急&#xff0c;你真的知道这两个的区别吗&#xff1f; 做过WEB开发的朋友可能很熟悉&#xff0c;看到这个问题能立马脱口而出二者的区别。 GET在浏览器回退时是无害的…

有赞电商云应用框架设计

背景 有赞是 SaaS 公司&#xff0c;向商家提供了全方位的软件服务&#xff0c;支撑商家进行采购、店铺、商品、营销、订单、物流等等管理服务。 在这个软件服务里&#xff0c;能够满足大部分的商家&#xff0c;为商家保驾护航。 但是很多大商家往往会有自己的特殊需求&#xff…

vivado 如何创建工程模式_基于Vivado的FPGA高性能开发研修班2019年8月30日上海举行...

一、课程介绍&#xff1a;从7系列FPGA开始&#xff0c;Xilinx提出了Vivado Design Suite设计软件&#xff0c;提供全新构建的SoC 增强型、以 IP 和系统为中心的下一代开发环境&#xff0c;以解决系统级集成和实现的生产力瓶颈。同时&#xff0c;Xilinx专门针对Vivado推出了Ultr…

程序员的自我修养——远离“外包思维”

*************************************优雅的分割线 ********************************** 分享一波:程序员赚外快-必看的巅峰干货 在我们做开发的日子里&#xff0c;不免会进行跳槽&#xff0c;跳来跳去公司无非就分成两大类——互联网公司、外包公司。当然我们本次讨论的并…

英特尔为 Kubernetes 推出分布式深度学习平台:Nauta

2019独角兽企业重金招聘Python工程师标准>>> 随着人工智能的发展&#xff0c;深度学习的价值不断增长&#xff0c;但实现它可能是一个复杂耗时的过程。英特尔(Intel)正寻求通过其在 Kubernetes 进行分布式深度学习的新开源平台来改变这一状况&#xff0c;该深度学习…

pytorch梯度下降函数_Pytorch中常用的四种优化器SGD、Momentum、RMSProp、Adam

来源&#xff1a;AINLPer微信公众号编辑: ShuYini校稿: ShuYini时间: 2019-8-16 引言很多人在使用pytorch的时候都会遇到优化器选择的问题&#xff0c;今天就给大家介绍对比一下pytorch中常用的四种优化器。SGD、Momentum、RMSProp、Adam。随机梯度下降法&#xff08;SGD&#…