Vue——计算属性和侦听属性
一、计算属性
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如,有一个嵌套数组对象:我们想根据 author 是否已经有一些书来显示不同的消息
<div id="computed-basics">
<p>Has published books:</p>
<span>{{ author.books.length > 0 ? 'Yes' : 'No' }}</span>
</div> <script> Vue.createApp({
data() {
return {
author: {
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
}
}
}
}).mount("#computed-basics")
</script>
此时,模板不再是简单的和声明性的。你必须先看一下它,然后才能意识到它执行的计算取决于 author.books。如果要在模板中多次包含此计算,则问题会变得更糟。
所以,对于任何包含响应式数据的复杂逻辑,你都应该使用计算属性。
<div id="computed-basics">
<p>Has published books:</p>
<span>{{ publishedBooksMessage }}</span>
</div> <script> Vue.createApp({
data() {
return {
author: {
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
}
}
},
computed: {
// 计算属性的 getter
publishedBooksMessage() {
// `this` 指向 vm 实例
return this.author.books.length > 0 ? 'Yes' : 'No'
}
}
}).mount('#computed-basics')
</script>
这里声明了一个计算属性 publishedBooksMessage。
尝试更改应用程序 data 中 books 数组的值,你将看到 publishedBooksMessage 如何相应地更改。
你可以像普通属性一样将数据绑定到模板中的计算属性。Vue 知道 vm.publishedBookMessage 依赖于 vm.author.books,因此当 vm.author.books 发生改变时,所有依赖 vm.publishedBookMessage 的绑定也会更新。
计算属性缓 vs 方法
你可能已经注意到我们可以通过在表达式中调用方法来达到同样的效果:
<p>{{ calculateBooksMessage() }}</p>
// 在组件中
methods: {
calculateBooksMessage() {
return this.author.books.length > 0 ? 'Yes' : 'No'
}
}
我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应依赖关系缓存的。计算属性只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 author.books 还没有发生改变,多次访问 publishedBookMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。 这也同样意味着下面的计算属性将不再更新,因为 Date.now () 不是响应式依赖:
computed: {
now() {
return Date.now()
}
}
相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。
我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 list,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 list。如果没有缓存,我们将不可避免的多次执行 list 的 getter!如果你不希望有缓存,请用 method 来替代。
案例:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.1.2/vue.global.js"></script>
<style>
body {
font-size: 14px;
} table, tr, th, td {
border: 1px solid red;
border-collapse: collapse; /* 合并边框 */
} th, td {
width: 200px;
text-align: center; /* 文本水平居中 */
height: 30px;
line-height: 30px;
} input {
width: 80px;
} .active {
background-color: lightskyblue;
}
</style>
</head>
<body> <div id="app">
<table>
<tr>
<th>商品ID</th>
<th>商品标题</th>
<th>商品库存</th>
<th>商品单价</th>
<th>购买数量</th>
<th>商品小计</th>
</tr>
<tr v-for="book in book_list">
<td>{{book.id}}</td>
<td>《{{book.title}}》</td>
<td>{{book.max_num}}</td>
<td>{{book.price}}</td>
<td>
<button @click="sub(book)">-</button>
<input type="text" v-model.number="book.num">
<button @click="add(book)">+</button>
</td>
<td>{{total(book)}}</td>
</tr>
<tr>
<td colspan="4"></td>
<td>总计</td>
<td>{{calc}}</td>
</tr>
</table>
</div> <script> Vue.createApp({
data() {
return {
book_list: [
{id: 10, title: "诛仙", price: 98.50, num: 1, max_num: 7,},
{id: 110, title: "元月", price: 68.50, num: 1, max_num: 5,},
{id: 30, title: "一月", price: 108.50, num: 1, max_num: 3,},
{id: 100, title: "二月", price: 78.50, num: 1, max_num: 10,},
]
}
},
// 所谓的计算属性,就是新声明一个新的变量,这个变量是经过data里面的数据运算后的结果。
computed: {
calc() {
let ret = 0;
this.book_list.forEach((book, key) => {
ret += book.price * book.num;
});
return ret.toFixed(2);
}
},
methods: {
total(book) {
return (book.price * book.num).toFixed(2);
},
sub(book) {
// 减少数量
if (book.num > 1) {
book.num -= 1;
}
},
add(book) {
// 增加数量
if (book.num < book.max_num) {
book.num += 1;
}
}
} }).mount('#app')
</script> </body>
</html>
二、侦听属性(监听属性)
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
侦听属性是一个对象,它的键是要监听的对象或者变量,值一般是函数,当侦听的data数据发生变化时,会自定执行的对应函数,这个函数在被调用时,vue会传入两个形参,第一个是变化前的数据值,第二个是变化后的数据值。
案例1:
<div id="computed-basics">
<p>{{num}}</p>
<p><input type="text" v-model="num"></p>
</div> <script> Vue.createApp({
data() {
return {
num: 10
}
},
watch: {
num: function (newval, oldval) {
//num发生变化的时候,要执行的代码
console.log(`num已经从${oldval}变成${newval}`);
}
} }).mount('#computed-basics')
</script>
案例2:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.1.2/vue.global.js"></script>
<style>
input[type=password] {
outline-color: red;
} input.is_pass {
outline-color: green;
} input.is_fail {
outline-color: red;
}
</style>
</head>
<body> <div id="app">
<p>
<input type="password" :class="tips" v-model="password">
</p>
</div> <script> Vue.createApp({
data() {
return {
tips: "is_fail",
password:""
}
},
watch: {
password() {
if (this.password.length > 6 && this.password.length < 16) {
this.tips = "is_pass"
} else {
this.tips = "is_fail";
}
}
}, }).mount('#app')
</script> </body>
</html>
Vue——计算属性和侦听属性的更多相关文章
- VUE 计算属性 vs 侦听属性
计算属性 vs 侦听属性 Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性.当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 ...
- 计算属性 vs 侦听属性 当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的
https://cn.vuejs.org/v2/guide/computed.html#基础例子 计算属性 vs 侦听属性 Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属 ...
- 浅谈vue中的计算属性和侦听属性
计算属性 计算属性用于处理复杂的业务逻辑 计算属性具有依赖性,计算属性依赖 data中的初始值,只有当初始值改变的时候,计算属性才会再次计算 计算属性一般书写为一个函数,返回了一个值,这个值具有依赖性 ...
- vue计算属性VS侦听属性
原文地址 Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性.当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 Angular ...
- 计算属性、侦听属性、局部与全局组件使用、组件通信(父子互传)、ref属性、动态组件和keep-alive、插槽
今日内容概要 计算属性 侦听属性 局部组件和全局组件 组件通信之父传子 组件通信之子传父 ref属性(组件间通信) 动态组件和keep-alive 插槽 内容详细 1.计算属性 # 插值的普通函数,只 ...
- Vue-计算属性和侦听属性
复杂逻辑应使用计算属性而不应写在插值表达式{{ }}里 <div id="app"> 原值:{{ msg }} <br> 翻转后的值:{{ reverseM ...
- [Web 前端] 034 计算属性,侦听属性
目录 0. 方便起见,定个轮廓 1. 过滤器 2. 计算属性 2.1 2.2 3. 监听属性 0. 方便起见,定个轮廓 不妨记下方的程序为 code1 <!DOCTYPE html> &l ...
- vue中计算属性和侦听属性
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- vue基础——计算属性和侦听器
计算属性——介绍 模板内的表达式非常便利,但是设计他们的初衷是用于简单计算的.在模板中放入太多的逻辑会让模板太过沉重切难以维护.如下: <div id="example"&g ...
- vue——计算属性和侦听器
一.计算属性(data中的相关数据) 侦听多个属性时——计算属性 comuted. 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的.在模板中放入太多的逻辑会让模板过重且难以维护.例如: & ...
随机推荐
- Push failed idea将项目发布到gitHub失败
此时需要点击VCS --> inport into version..-->create git ...重新生成仓库
- 挑战吧,HarmonyOS应用开发工程师
一年一度属于工程师的专属节日1024已过,但程序员多重活动持续进行中~ 参与活动即有机会获得HUAWEI Freebuds 5i 耳机等精美礼品! 点击"阅读原文"查看更多活动 ...
- .NET Emit 入门教程:第六部分:IL 指令:9:详解 ILGenerator 指令方法:运算操作指令(指令篇结束)
前言: 经过前面几篇的学习,我们了解到指令的大概分类,如: 参数加载指令,该加载指令以 Ld 开头,将参数加载到栈中,以便于后续执行操作命令. 参数存储指令,其指令以 St 开头,将栈中的数据,存储到 ...
- 【笔记】greatest/least函数&Round函数
刷了一下力扣,发现有很多的函数是自己不清楚的,用了这些函数是比较容易得出结果的,不用自己费心去实现一些奇怪的东西 1.最大最小值 链接:https://leetcode.cn/problems/num ...
- 力扣35(java&python)-搜索插入位置(简单)
题目: 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引.如果目标值不存在于数组中,返回它将会被按顺序插入的位置. 请必须使用时间复杂度为 O(log n) 的算法. 示例 1: 输入: ...
- 力扣901(java&python)-股票价额跨度(中等)
题目: 编写一个 StockSpanner 类,它收集某些股票的每日报价,并返回该股票当日价格的跨度. 今天股票价格的跨度被定义为股票价格小于或等于今天价格的最大连续日数(从今天开始往回数,包括今天) ...
- 安全同学讲Maven间接依赖场景的仲裁机制
简介: 去年的Log4j-core的安全问题,再次把供应链安全推向了高潮.在供应链安全的场景,蚂蚁集团在静态代码扫描平台-STC和资产威胁透视平台-哈勃这2款产品在联合合作下,优势互补,很好的解决了直 ...
- Flink 实时计算在微博的应用
简介: 微博通过将 Flink 实时流计算框架跟业务场景相结合,在平台化.服务化方面做了很大的工作,在开发效率.稳定性方面也做了很多优化.我们通过模块化设计和平台化开发,提高开发效率. 微博机器学习研 ...
- 解密 Dubbo 三大中心的部署架构
简介:Dubbo作为一个微服务框架,Dubbo SDK与应用服务绑定在同一个进程内,它跟随着应用服务被部署在分布式集群各个位置,为了在分布式环境下实现各个应用服务间的协作, Dubbo 定义了一些中 ...
- Dubbo3.0|阿里巴巴服务框架三位一体的选择与实践
简介: 服务框架就像铁路的铁轨一样,是互通的基础,只有解决了服务框架的互通,才有可能完成更高层的业务互通,所以用相同的标准统一,合二为一并共建新一代的服务框架是必然趋势.Dubbo3.0 是 Dub ...