一、计算属性

模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如,有一个嵌套数组对象:我们想根据 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. 容器开发运维人员的 Linux 操作机配置优化建议

    "工欲善其事必先利其器", 作为一个PAAS平台架构师, 容器相关技术(docker, k8s等)是必不可少的. 本文简单介绍下我自己的Linux操作机配置. 提升工作效率, 提高 ...

  2. Kubernetes 的 NameSpace 无法删除应该怎么办?

    概述 有时候我们操作不规范,或者删除的先后顺序有问题,或者某项关键服务没有启动,导致 Kubernetes 经常会出现无法删除 NameSpace 的情况.这种情况下我们应该怎么办? 规范删除流程 其 ...

  3. JavaScript中的事件模型如何理解?

    一.事件与事件流 javascript中的事件,可以理解就是在HTML文档或者浏览器中发生的一种交互操作,使得网页具备互动性, 常见的有加载事件.鼠标事件.自定义事件等 由于DOM是一个树结构,如果在 ...

  4. 聊聊从大模型来看NLP解决方案之UIE

    转载请备注出处:https://www.cnblogs.com/zhiyong-ITNote 概述 自然语言处理NLP任务的实现,相比较以前基于传统机器学习算法实现方法,现在越来越集中使用大模型来实现 ...

  5. 第12課-Mirth生产环境宕机后基于服务配置XML备份恢复之记录

    Mirth Connect作为集成交换平台,生产环境互联互通了众多系统,脑残的是连自家关键业务系统都依托mirth来进行交互,宕机或故障对身处其中的一次紧张的业务系统升级都造成高度的精神紧张:这种宕机 ...

  6. 《最新出炉》系列入门篇-Python+Playwright自动化测试-40-录制生成脚本

    1.简介 各种自动化框架都会有脚本录制功能, playwright这么牛叉当然也不例外.很早之前的selenium.Jmeter工具,发展到每种浏览器都有对应的录制插件.今天我们就来看下微软自动化框架 ...

  7. Nacos 开源、自研、商业化三位一体战略解读

    简介: Nacos作为整个阿里云原生三位战略中的核心组成部分,我们在2018年以Configserver/VIPServer/Diamond为基础通过Nacos开源输出阿里十年沉淀的注册中心和配置中心 ...

  8. [FAQ] dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.64.dylib

    通过 ls -al /usr/local/opt 可以看到 icu4c 链接的不是 libicui18n.64.dylib. 一般是 node 版本问题会出现该提示,通过观察版本大小,决定是升级还是使 ...

  9. dotnet6 C# 一个国内还能用的 NTP 时间校准客户端的实现

    本文来记录一个我自己在使用的 NTP 时间校准客户端的实现 核心方法是在国内使用 腾讯 和 阿里 提供的 NTP 时间服务器来获取网络时间,如果连接不上,再依次换成 国家服务器 和 中国授时 服务,如 ...

  10. WPF 笔迹触摸点收集工具

    本文来安利大家一个工具,可以用来收集笔迹的触摸点,这个工具完全开源 在开始之前先看一下工具的界面 实现方式其实就在触摸的时候收集触摸点信息,上面的工具有很多功能都没有实现的.笔迹绘制的功能使用 WPF ...