11 Vue3中的computed计算属性

概述

Computed properties are unique data types that will reactively update only when the source data used within the property is updated. By defining a data property as a computed property, we can perform the following activities:

  • Apply custom logic on the original data property to calculate the computed property’s value
  • Track the changes of the original data property to calculate the updated value of the computed property
  • Reuse the computed property as local data anywhere within the Vue component

计算属性是一种独特的数据类型,只有在属性中使用的源数据更新时才会被动更新。通过将数据属性定义为计算属性,我们可以执行以下活动:

  • 在原始数据属性上应用自定义逻辑,计算计算属性的值

  • 跟踪原始数据属性的变化,计算计算属性的更新值

  • 在 Vue 组件中的任何位置将计算属性作为本地数据重复使用

By default, the Vue engine automatically caches the computed properties, making them more performant at updating the UI than using the property of the returned value of data, or using a Vue component’s method.

默认情况下,Vue 引擎会自动缓存计算属性,这使得它们在更新 UI 时比使用数据返回值的属性或使用 Vue 组件的方法更高效。

The syntax of a computed property is like writing a component method with a return value, nested under the computed property of the Vue component:

计算属性的语法就像编写一个带有返回值的组件方法,嵌套在 Vue 组件的计算属性下:

<script>
export default {computed: {yourComputedProperty() {/* need to have return value */}}
}
</script>

Within the computed property’s logic, you can access any component’s data property, method, or other computed property using the this instance, which is the reference to the Vue component instance itself. An example of using the this instance is shown here:

在计算属性的逻辑中,你可以使用 this 实例访问任何组件的数据属性、方法或其他计算属性,this 实例是对 Vue 组件实例本身的引用。下面是一个使用 this 实例的示例:

<script>
export default {data() {return {yourData: "your data"}},computed: {yourComputedProperty() {return `${this.yourData}-computed`;}}
}
</script>

计算属性的使用场景

Let’s look at some examples of where you should consider using a computed property.

让我们举例说明在哪些情况下应考虑使用计算属性。

表单校验

In the following example, we have an input field, which attaches to the name data property, and error is a computed property. If name contains a falsy value (which means name is an empty string, 0, undefined, null, or false), error will be assigned a value of “Name is required”. Otherwise, it will be empty.

在下面的示例中,我们有一个与 name 数据属性相连的输入字段,而 error 是一个计算属性。如果 name 包含虚假值(即 name 为空字符串、0、未定义、空或 false),error 将被赋值为 “Name is required”。否则,该值将为空。

The component then renders the value of the error property accordingly:

然后,组件会相应地渲染错误属性的值:

<template><input v-model="name"><div><span>{{ error }}</span></div>
</template>
<script>
export default {data() {return {name: '',}},computed: {error() {return this.name ? '' : 'Name is required'}}
}
</script>

合并数据属性

You can use computed props to combine multiple data properties to generate a single computed property. Take the following code for instance. We combine two pieces of data – title and surname – into one computed string, formalName, and render its value using template:

你可以使用计算道具来组合多个数据属性,生成一个计算属性。以下面的代码为例。我们将标题和姓氏这两个数据合并为一个计算字符串 formalName,并使用模板呈现其值:

<template><div>{{ formalName }}</div>
</template>
<script>
export default {data() {return {title: 'Mr.',surname: 'Smith'}},computed: {formalName() {return `${this.title} ${this.surname}`;}}
}
</script>

计算和显示复杂信息

Sometimes there is a need to perform an extra calculation or to extract specific information from one large data object source. Computed properties help to achieve this goal while keeping our code readable.

有时需要执行额外的计算,或从一个大型数据对象源中提取特定信息。计算属性有助于实现这一目标,同时保持代码的可读性。

Take a large data object, such as post. This data object has a nested fields property, which contains several additional information objects, such as the full name of author and an array of entries objects. Each entry in entries contains further information, such as title, content, and a feature flag indicating whether the entry should be featured:

以一个大型数据对象为例,如 post。该数据对象有一个嵌套字段属性,其中包含多个附加信息对象,如作者全名和条目对象数组。条目中的每个条目都包含更多信息,如标题、内容和表示条目是否应被突出显示的特征标志:

<script>
export default {data() {return {post: {fields: {author: {firstName: 'John',lastName: 'Doe'},entries: [{title: "Entry 1",content: "Entry 1's content",featured: true},{title: "Entry 2",content: "Entry 2's content",featured: false}]}}}},
}
</script>

In this scenario, you need to perform the following steps:

  • Display the full name of the post’s author.
  • Calculate and display the total number of entries included.
  • Display a list of entries that have the feature flag turned on (feature: true).

在这种情况下,您需要执行以下步骤:

  • 显示帖子作者的全名。
  • 计算并显示包含的条目总数。
  • 显示已打开特征标志(特征:true)的条目列表。

By using computed properties, we can decouple the previous post object into several computed data properties while keeping the original post object unchanged, as follows.

通过使用计算属性,我们可以将之前的文章对象解耦为多个计算数据属性,同时保持原始文章对象不变,如下所示。

<script>
export default {data() {return {post: {fields: {author: {firstName: 'John',lastName: 'Doe'},entries: [{title: "Entry 1",content: "Entry 1's content",featured: true},{title: "Entry 2",content: "Entry 2's content",featured: false}]}}}},computed: {// fullName 用于合并 post.fields.author 的名和姓:fullName() {const {firstName, lastName} =this.post.fields.author;return `${firstName} ${lastName}`},// totalEntries 包含 post.fields.entries 数组的长度:totalEntries () {return this.post.fields.entries.length},// featuredEntries 包含根据每个条目的特征属性过滤后的 post.fields.entries 列表,使用的是 filter 内置数组方法:featuredEntries() {const { entries } = this.post.fields;return entries.filter(entry => !!entry.featured)}}
}
</script>

You then use the simplified and semantic computed properties to render the information in your component’s template.

然后,使用简化和语义计算属性在组件模板中呈现信息。

<template><div><p>{{ fullName }}</p><p>{{ totalEntries }}</p><p>{{ featuredEntries }}</p></div>
</template>

Computed properties are very valuable to Vue developers when creating performant components. In the next exercise, we will explore how to use them inside a Vue component.

在创建高性能组件时,计算属性对 Vue 开发人员非常有价值。在下一个练习中,我们将探讨如何在 Vue 组件中使用它们。

练习:使用计算属性

In this exercise, you will use a computed property to help cut down the amount of code you need to write inside your Vue templates by concisely outputting basic data.

在本练习中,您将使用计算属性,通过简洁地输出基本数据,帮助减少 Vue 模板中需要编写的代码量。

Let’s create a new Vue component called Exercise2-01 by adding the Exercise2-01.vue file to the ./src/components/ folder:

让我们在 ./src/components/ 文件夹中添加 Exercise2-01.vue 文件,创建一个名为 Exercise2-01 的新 Vue 组件:

在App.vue中,引入并使用该组件:

<script setup>
import Exercise from "./components/Exercise2-01.vue";
</script>
<template><Exercise/>
</template>

Open Exercise2-01.vue and let’s create the code block structure for the Vue component, as follows:

打开 Exercise2-01.vue,为 Vue 组件创建代码块结构,如下所示:

<template>
</template>
<script>
export default {
}
</script>

In <template>, create an input field for the first name, and use v-model to bind the data prop, firstName, to this field:

<template> 中,为名字创建一个输入字段,并使用 v-model 将数据道具 firstName 绑定到该字段:

<input v-model="firstName" placeholder="First name" />

Create a second input field for the last name, and use v-model to bind the data prop, lastName, to this field:

为姓氏创建第二个输入字段,并使用 v-model 将数据道具 lastName 与该字段绑定:

<input v-model="lastName" placeholder="Last name" />

Include these new v-model data props in the Vue instance by returning them in the data() function:

通过在 data() 函数中返回这些新的 v 模型数据道具,将其包含在 Vue 实例中:

<script>
export default {data() {return {firstName: '',lastName: '',}},
}
</script>

Create a computed data variable called fullName:

创建名为 fullName 的计算数据变量:

<script>
export default {data() {return {firstName: '',lastName: '',}},computed: {fullName() {return '${this.firstName} ${this.lastName}'},},
}
</script>

Underneath your input fields, output the computed data using the h3 tag:

在输入字段下方,使用 h3 标签输出计算数据:

<template><input v-model="firstName" placeholder="First name" /><input v-model="lastName" placeholder="Last name" /><h3 class="output">{{ fullName }}</h3>
</template>

This exercise demonstrates how we can write an expression inside a computed data property using data received from v-model, and then combine the first name and last name into a single output variable with the fullName computed property that can be reused within the component.

本练习演示了如何使用从 v-model 收到的数据在计算数据属性内编写表达式,然后将姓和名与可在组件内重复使用的计算属性 fullName 结合为一个输出变量。

We now understand how a computed property works and how to write a declarative, reusable, and reactive computed property. Next, we will look at how to intercept the mutation process of a computed property and add additional logic with the computed setter feature.

现在,我们了解了计算属性的工作原理,以及如何编写声明式、可重用和反应式的计算属性。接下来,我们将了解如何拦截计算属性的突变过程,并使用计算设置器功能添加附加逻辑。

修改计算属性的值

By default, computed data is a getter only, which means it will only output the outcome of your expression. In some practical scenarios, when a computed property is mutated, you may need to trigger an external API or mutate the original data elsewhere in the project. The function performing this feature is called a setter.

默认情况下,计算数据只是一个 getter,这意味着它只会输出表达式的结果。在某些实际场景中,当计算属性发生变化时,您可能需要触发外部 API 或在项目的其他地方对原始数据进行变化。执行此功能的函数称为设置器。

Using a setter in a computed property allows you to reactively listen to data and trigger a callback (setter) that contains the returned value from the getter, which can optionally be used in the setter.

在计算属性中使用设置器,可以对数据进行反应式监听,并触发一个回调(设置器),其中包含从获取器返回的值,该值可选择用于设置器。

But first, let’s look at JavaScript ES5’s getter and setter. Starting from ES5, you can use the built-in getter and setter to define Object accessors, such as the following:

不过,首先让我们了解一下 JavaScript ES5 的 getter 和 setter。从 ES5 开始,您可以使用内置的 getter 和 setter 来定义对象访问器,例如下面的内容:

get to bind the Object property to a function that returns a value for that property whenever it is looked up, as shown here:

将对象属性绑定到一个函数,该函数会在每次查询时返回该属性的值,如图所示:

const obj = {get example() {return 'Getter'}
}
console.log(obj.example) //Getter

set to bind the specific Object property to a function whenever that property is modified:

设置,以便在修改特定对象属性时将该属性绑定到一个函数:

const obj = {set example(value) {this.information.push(value)},information: []
}
obj.example = 'hello'
obj.example = 'world'
console.log(obj.information) //['hello', 'world']

Based on those features, Vue.js provides us with similar functionalities, get() as the getter and set() as the setter, for a specific computed property:

基于这些功能,Vue.js 为我们提供了类似的功能,即针对特定的计算属性,将 get() 作为获取器,将 set() 作为设置器:

<script>
export default {computed: {myComputedDataProp: {get() {},set(value) {}}}
}
</script>

To understand how setter and getter work, let’s perform the following steps:

要了解 setter 和 getter 如何工作,让我们执行以下步骤:

Define the returned value of myComputedDataProp to be this.count + 1 whenever myComputedDataProp is looked up:

定义每次查询 myComputedDataProp 时,myComputedDataProp 的返回值为 this.count + 1:

<script>
export default {computed: {myComputedDataProp: {get() {return this.count + 1},set(value) {}}}
}
</script>

Then, whenever myComputedDataProp is modified, use the setter to update the count data prop to its new value, and then call a method within the component called callAnotherApi with this new this.count value:

然后,每当修改 myComputedDataProp 时,使用设置器将计数数据道具更新为新值,然后使用新的 this.count 值调用组件中名为 callAnotherApi 的方法:

<script>
export default {computed: {myComputedDataProp: {get() {return this.count + 1},set(value) {this.count = value - 1this.callAnotherApi(this.count)}}}
}
</script>

With count and callAnotherApi is the component’s local data and method, respectively.

其中,count 和 callAnotherApi 分别是组件的本地数据和方法。

The full example code is as follows:

完整的示例代码如下:

<template><h1>原始值:{{ count }}</h1><h1>属性值:{{ myComputedDataProp }}</h1><button @click="myComputedDataProp+=33">修改属性的值</button>
</template>
<script>
export default {data() {return {count: 0}},computed: {myComputedDataProp: {get() {return this.count + 1},set(value) {this.count = value - 1},},},
}
</script>

Here the computed myComputedDataProp prop will output 1 in your Vue component.

在这里,计算后的 myComputedDataProp 将在 Vue 组件中输出 1。

You will find out exactly how to use computed data as both getters and setters in the following exercise.

您将在下面的练习中了解如何将计算数据作为获取器和设置器使用。

练习:修改计算属性值

In this exercise, you will use a computed prop as a setter and a getter, which will both output expressions and set data when triggered by a user’s input.

在本练习中,你将使用一个计算道具作为设置器和获取器,当用户输入触发时,它将同时输出表达式和设置数据。

Let’s create a new Vue component called Exercise2-02 by adding the Exercise2-02.vue file to the ./src/components/ folder.

让我们在 ./src/components/ 文件夹中添加 Exercise2-02.vue 文件,创建一个名为 Exercise2-02 的新 Vue 组件。

修改App.vue,引入该组件并使用:

<script setup>
import Exercise from "./components/Exercise2-02.vue";
</script>
<template><Exercise/>
</template>

Open Exercise2-02.vue and let’s create the code block structure for the Vue component, as follows:

打开 Exercise2-02.vue,创建 Vue 组件的代码块结构如下:

<template>
</template>
<script>
export default {}
</script>

Create an input field with a v-model value bound to a computed data value called incrementOne, return the value of a Vue data variable called count in the getter, and set the count variable in the setter:

创建一个输入字段,其 v 模型值绑定到名为 incrementOne 的计算数据值,在 getter 中返回名为 count 的 Vue 数据变量的值,并在 setter 中设置 count 变量:

<template><div class="container"><input type="number" v-model="incrementOne" /><h3>Get input: {{ incrementOne }}</h3></div>
</template>
<script>
export default {data() {return {count: -1,}},computed: {incrementOne: {get() {return this.count + 1},set(val) {this.count = val - 1},},},
}
</script>

Next, let’s utilize the setter again. We will divide whatever the new val argument is by 2, and save that to a new data variable called divideByTwo:

接下来,让我们再次使用 setter。我们将用新的 val 参数除以 2,并将其保存到一个名为 divideByTwo 的新数据变量中:

<template><div class="container"><input type="number" v-model="incrementOne" /><h3>Get input: {{ incrementOne }}</h3><h5>Set division: {{ divideByTwo }}</h5></div>
</template>
<script>
export default {data() {return {count: -1,divideByTwo: 0,}},computed: {incrementOne: {get() {return this.count + 1},set(val) {this.count = val - 1},},},
}
</script>

Update the setter to divide val by 2, and bind this new value to the divideByTwo variable:

更新设置器,将 val 除以 2,并将新值绑定到 divideByTwo 变量:

<template><div class="container"><input type="number" v-model="incrementOne"/><h3>Get input: {{ incrementOne }}</h3><h5>Set division: {{ divideByTwo }}</h5></div>
</template>
<script>
export default {data() {return {count: -1,divideByTwo: 0,}},computed: {incrementOne: {get() {return this.count + 1},set(val) {this.count = val - 1this.divideByTwo = val / 2},},},
}
</script>

This exercise demonstrates how we can use computed data to both get and set data reactively in our template by binding computed variables to the vmodel.

本练习演示了如何通过将计算变量绑定到 vmodel,在模板中使用计算数据来获取和设置数据。

In the next section, we will explore how we can use watchers to actively listen to changes in component data or its property.

在下一节中,我们将探讨如何使用观察者来主动监听组件数据或其属性的变化。

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

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

相关文章

【ssh基础知识】

ssh基础知识 常用命令登录流程配置文件ssh密钥登录生成密钥上传公钥关闭密码登录 ssh服务管理查看日志ssh端口转发 ssh&#xff08;ssh客户端&#xff09;是一个用于登录到远程机器并在远程机器上执行命令的程序。 它旨在提供安全的加密通信在不安全的网络上的两个不受信任的主…

07 使用v-for实现循环渲染

概述 To loop over HTML elements in Vue, you use the v-for loop directive directly on the target elements. When Vue renders the component, it will iterate the target to use and render the data being parsed into the directive, with the same concept as a nor…

代码随想录27期|Python|Day16|二叉树|104.二叉树的最大深度|111.二叉树的最小深度|222.完全二叉树的节点个数

二叉树专题&#xff0c;重点掌握后续的递归和中间节点的处理。 104. 二叉树的最大深度 - 力扣&#xff08;LeetCode&#xff09; 本题在前一章已经解决了层序遍历的解法&#xff0c;现在来聊一下递归法。 首先需要明确两个概念&#xff1a;深度和高度。&#xff08;注意&…

双向数据123

1. 原理 双向数据绑定的原理是使用数据劫持&#xff08;或者称为响应式&#xff09;和事件监听。当数据发生变化时&#xff0c;会触发视图的更新&#xff1b;同时&#xff0c;当用户与视图进行交互&#xff08;如在输入框中输入文字&#xff09;&#xff0c;变化会反映到数据模…

conda操作命令汇总

目录 conda命令&#xff1a;环境的创建与删除包&#xff08;第三方库&#xff09;的安装与卸载 参考链接 conda命令&#xff1a;环境的创建与删除 1.查看自己配置的环境 conda env list2.配置一个新的环境 conda create -n 环境的名字 python版本号3.进入和退出环境 activa…

抠图软件哪个好用?什么软件可以抠图换背景?

抠图软件哪个好用&#xff1f;在图片处理中&#xff0c;抠图换背景是一项常见的操作。很多新手可能会对此感到困惑&#xff0c;不知道应该使用什么软件来进行抠图换景。实际上&#xff0c;现在市面上有很多图片处理软件都具备抠图换背景的功能&#xff0c;每款软件都有其优缺点…

静态代理和动态代理的区别,什么场景使用

文章目录 静态代理和动态代理的区别&#xff0c;什么场景使用&#xff1f;静态代理&#xff1a;动态代理&#xff1a;实现步骤&#xff1a;使用场景&#xff1a; 静态代理和动态代理的区别&#xff0c;什么场景使用&#xff1f; 代理是一种常用的设计模式&#xff0c;目的是&a…

LVS负载均衡群集部署 DR模式

目录 DR模式直接路由 LVS-DR工作原理 LVS-DR 数据包流向分析 DR 模式的特点 DR模式 LVS负载均衡群集部署 DR模式直接路由 Direct Routing&#xff0c;简称DR模式&#xff0c;采用半开放式的网络结构&#xff0c;与TUN模式的结构类似&#xff0c;但各节点并不是分散在各地…

c语言链表的基本操作

在C语言中&#xff0c;链表是一种常见的数据结构&#xff0c;它由一系列节点组成&#xff0c;每个节点包含一个数据元素和一个指向下一个节点的指针。链表的基本操作包括创建、插入、删除和遍历等。 下面是一个简单的链表节点结构体定义&#xff1a; struct Node { int da…

Python实现员工管理系统(Django页面版 ) 六

本篇博客主要实现用户账号管理&#xff0c;这与之前的账号管理不同&#xff0c;之前的账号管理你可以理解为公司在外面买的一些手机号然后需要发放给员工做内部使用&#xff0c;而本篇博客的用户账号管理主要是为了后续的登录网页实现&#xff0c;那么我们开始今天的项目实现吧…

392. 判断子序列

双指针 class Solution {public boolean isSubsequence(String s, String t) {int i 0, j 0;while (i < s.length() && j < t.length()) {if (s.charAt(i) ! t.charAt(j)) {j;} else {i;j;}}if (i s.length()) return true;else return false;} }*有余力可以…

2. 套圈(分治)

题目 Have you ever played quoit in a playground? Quoit is a game in which flat rings are pitched at some toys, with all the toys encircled awarded. In the field of Cyberground, the position of each toy is fixed, and the ring is carefully designed so it c…

搭建消息时光机:深入探究RabbitMQ_recent_history_exchange在Spring Boot中的应用【RabbitMQ实战 二】

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 搭建消息时光机&#xff1a;深入探究RabbitMQ_recent_history_exchange在Spring Boot中的应用 引言前言第一&#xff1a;开启插件支持第二&#xff1a;springboot整合第三&#xff1a;效果展示交换机属…

locust 压测 websocket

* 安装 python 3.8 https://www.python.org/ py --version * 安装 locust pip install locust2.5.1 -i http://pypi.douban.com/simple/ pip install locust2.5.1 -i https://pypi.mirrors.ustc.edu.cn/simple/ locust -V 备注&#xff1a;-i 是切换下载源 * 安装依赖 pip ins…

Electron框架:构建跨平台桌面应用的终极解决方案

文章目录 一、Electron框架简介二、Electron框架的优势1. 开发效率高2. 跨平台性能好3. 易于维护4. 强大的原生能力 三、如何使用Electron框架快速开发跨平台桌面应用1. 安装Electron2. 创建项目文件夹3. 编写主进程代码4. 编写界面代码5. 运行应用 《Electron入门与实战》编辑…

《软件方法》2023版1.1利润=需求-设计1.2 ABCD工作流

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 第1章 建模和UML 牵着你走进傍晚的风里&#xff0c;看见万家灯火下面平凡的秘密。 《情歌唱晚》&#xff1b;词&#xff1a;黄群&#xff0c;曲&#xff1a;黄群&#xff0c;唱&#…

word文档实现“目录索引中标题加粗、前导符(...)和页码不加粗”效果

文章目录 1 展示论文模板需要呈现的效果2 所遇到的问题2.1 情形1&#xff1a;当更新整个目录后&#xff0c;目录中的所有文字都不加粗2.2 情形2&#xff1a;无法单独选中文字部分&#xff0c;如果相对文字部分加粗&#xff0c;则前导符和页码也会同时加粗 3 解决步骤3.1 步骤1&…

CIDR(无类域间路由)与VLSM(可变长度子网掩码)的区别

CIDR和VLSM的介绍 CIDR CIDR&#xff08;Classless Inter-Domain Routing&#xff0c;无类域间路由&#xff09;是一种用于对互联网协议&#xff08;IP&#xff09;地址进行聚合和分配的标准。CIDR的引入旨在解决IPv4地址空间的不足和低效分配的问题。在传统的IP地址规划中&a…

关键点检测之修改labelme标注的json中类别名

import json import os import shutil#source_dir表示数据扩增之后的文件夹路径&#xff0c;此时标注的是多分类的标签 #new_dir表示转化之后得到的二分类文件夹def to2class():#json存放路径source_dir r1#json保存路径new_dir r1for i in os.listdir(source_dir):if i.ends…

文本聚类——文本相似度(聚类算法基本概念)

一、文本相似度 1. 度量指标&#xff1a; 两个文本对象之间的相似度两个文本集合之间的相似度文本对象与集合之间的相似度 2. 样本间的相似度 基于距离的度量&#xff1a; 欧氏距离 曼哈顿距离 切比雪夫距离 闵可夫斯基距离 马氏距离 杰卡德距离 基于夹角余弦的度量 公式…