一、计算属性

模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如,有一个嵌套数组对象:我们想根据 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——计算属性和侦听属性的更多相关文章

  1. VUE 计算属性 vs 侦听属性

    计算属性 vs 侦听属性 Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性.当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 ...

  2. 计算属性 vs 侦听属性 当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的

    https://cn.vuejs.org/v2/guide/computed.html#基础例子 计算属性 vs 侦听属性 Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属 ...

  3. 浅谈vue中的计算属性和侦听属性

    计算属性 计算属性用于处理复杂的业务逻辑 计算属性具有依赖性,计算属性依赖 data中的初始值,只有当初始值改变的时候,计算属性才会再次计算 计算属性一般书写为一个函数,返回了一个值,这个值具有依赖性 ...

  4. vue计算属性VS侦听属性

    原文地址 Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性.当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 Angular ...

  5. 计算属性、侦听属性、局部与全局组件使用、组件通信(父子互传)、ref属性、动态组件和keep-alive、插槽

    今日内容概要 计算属性 侦听属性 局部组件和全局组件 组件通信之父传子 组件通信之子传父 ref属性(组件间通信) 动态组件和keep-alive 插槽 内容详细 1.计算属性 # 插值的普通函数,只 ...

  6. Vue-计算属性和侦听属性

    复杂逻辑应使用计算属性而不应写在插值表达式{{ }}里 <div id="app"> 原值:{{ msg }} <br> 翻转后的值:{{ reverseM ...

  7. [Web 前端] 034 计算属性,侦听属性

    目录 0. 方便起见,定个轮廓 1. 过滤器 2. 计算属性 2.1 2.2 3. 监听属性 0. 方便起见,定个轮廓 不妨记下方的程序为 code1 <!DOCTYPE html> &l ...

  8. vue中计算属性和侦听属性

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. vue基础——计算属性和侦听器

    计算属性——介绍 模板内的表达式非常便利,但是设计他们的初衷是用于简单计算的.在模板中放入太多的逻辑会让模板太过沉重切难以维护.如下: <div id="example"&g ...

  10. vue——计算属性和侦听器

    一.计算属性(data中的相关数据) 侦听多个属性时——计算属性 comuted. 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的.在模板中放入太多的逻辑会让模板过重且难以维护.例如: & ...

随机推荐

  1. Java程序员常用英语整理

    基础----进阶 A. array数组accessible 可存取的 area面积audio 音频 addition 加法 action 行动 arithmetic 算法adjustment 调整 a ...

  2. HarmonyOS应用事件打点开发指导

      简介 传统的日志系统里汇聚了整个设备上所有程序运行的过程流水日志,难以识别其中的关键信息.因此,应用开发者需要一种数据打点机制,用来评估如访问数.日活.用户操作习惯以及影响用户使用的关键因素等关键 ...

  3. DevEco Studio新特性分享-跨语言调试,让调试更便捷高效

     原文:https://mp.weixin.qq.com/s/JKVLQXu1z1zAoF5q49YEGg,点击链接查看更多技术内容.   HUAWEI DevEco Studio是开发Harmony ...

  4. GAN的一些问题

    GAN为什么难以训练? 大多深度模型的训练都使用优化算法寻找损失函数比较低的值.优化算法通常是个可靠的"下山"过程.生成对抗神经网络要求双方在博弈的过程中达到势均力敌(均衡).每个 ...

  5. BI、OLAP、多维分析、CUBE 这几个词是什么关系?

    这些词我们在建设分析型应用时经常会听到,这几个词也经常被弄混,这里来梳理一下. BIBI 是 Business Intelligence(商业智能)的缩写,是指企业利用已有数据进行数据分析从而指导商业 ...

  6. 哨兵的多个核心底层原理的深入解析(包含slave选举算法)

    一.sdown和odown转换机制sdown和odown两种失败状态 sdown是主观宕机,就一个哨兵如果自己觉得一个master宕机了,那么就是主观宕机odown是客观宕机,如果quorum数量的哨 ...

  7. MySQL 分析查询与来源机器

    当前分析针对版本:MariaDB 10.5 线上出现报错:can't create more than max_prepared_stmt_count statements.造成这个错误的直接原因就是 ...

  8. 力扣607(MySQL)-销售员(简单)

    题目: 表: SalesPerson 表: Company 表: Orders 编写一个SQL查询,报告没有任何与名为 "RED" 的公司相关的订单的所有销售人员的姓名. 以 任意 ...

  9. [GPT] nodejs 什么情况下可以使用 import 来引入 export 的模块

    在 Node.js 中,原生并不支持 ES6 的 import 语句来引入模块. 不过从 Node.js v12 开始,通过实验性功能(--experimental-modules)可以使用 .mjs ...

  10. [Go] freecache 设置 SetGCPercent 的作用

    你需要对 freecache 有一个大致了解,freecache 的内存空间是预分配的. 假设你的程序占用了 50M 内存,那么开启 freecache 预分配 200M 空间,总共下来就是 250M ...