Vue学习之计算属性

模板中的表达式虽然方便,但也只能用来做简单的操作。如果在模板中写太多逻辑,会让模板变得臃肿,难以维护。比如说,我们有这样一个包含嵌套数组的对象:

const author = reactive({
  name: 'John Doe',
  books: [
    'Vue 2 - Advanced Guide',
    'Vue 3 - Basic Guide',
    'Vue 4 - The Mystery'
  ]
})

我们想根据 author 是否已有一些书籍来展示不同的信息:

<p>Has published books:</p>
<span>{{ author.books.length > 0 ? 'Yes' : 'No' }}</span>

这里的模板看起来有些复杂。我们必须认真看好一会儿才能明白它的计算依赖于 author.books。更重要的是,如果在模板中需要不止一次这样的计算,我们可不想将这样的代码在模板里重复好多遍。

因此我们推荐使用计算属性来描述依赖响应式状态的复杂逻辑。这是重构后的示例:

vue

<script setup>
import { reactive, computed } from 'vue'
//reactive用于对象或者数组,ref常用于字符串
const author = reactive({
  name: 'John Doe',
  books: [
    'Vue 2 - Advanced Guide',
    'Vue 3 - Basic Guide',
    'Vue 4 - The Mystery'
  ]
})

// 一个计算属性 ref
const publishedBooksMessage = computed(() => {
  return author.books.length > 0 ? 'Yes' : 'No'
})
</script>

<template>
  <p>Has published books:</p>
  <span>{{ publishedBooksMessage }}</span>
</template>

我们在这里定义了一个计算属性 publishedBooksMessage。computed() 方法期望接收一个 getter 函数,返回值为一个计算属性 ref。和其他一般的 ref 类似,你可以通过 publishedBooksMessage.value 访问计算结果。计算属性 ref 也会在模板中自动解包,因此在模板表达式中引用时无需添加 .value。

Vue 的计算属性会自动追踪响应式依赖。它会检测到 publishedBooksMessage 依赖于 author.books,所以当 author.books 改变时,任何依赖于 publishedBooksMessage 的绑定都会同时更新。

也可参考:为计算属性标注类型

计算属性缓存 vs 方法 ​

你可能注意到我们在表达式中像这样调用一个函数也会获得和计算属性相同的结果:

template
<p>{{ calculateBooksMessage() }}</p>
js
// 组件中
function calculateBooksMessage() {
  return author.books.length > 0 ? 'Yes' : 'No'
}

若我们将同样的函数定义为一个方法而不是计算属性,两种方式在结果上确实是完全相同的,然而,不同之处在于计算属性值会基于其响应式依赖被缓存。一个计算属性仅会在其响应式依赖更新时才重新计算。这意味着只要 author.books 不改变,无论多少次访问 publishedBooksMessage 都会立即返回先前的计算结果,而不用重复执行 getter 函数。

这也解释了为什么下面的计算属性永远不会更新,因为 Date.now() 并不是一个响应式依赖:

js

const now = computed(() => Date.now())

相比之下,方法调用总是会在重渲染发生时再次执行函数。

为什么需要缓存呢?想象一下我们有一个非常耗性能的计算属性 list,需要循环一个巨大的数组并做许多计算逻辑,并且可能也有其他计算属性依赖于 list。没有缓存的话,我们会重复执行非常多次 list 的 getter,然而这实际上没有必要!如果你确定不需要缓存,那么也可以使用方法调用。

可写计算属性 ​

计算属性默认是只读的。当你尝试修改一个计算属性时,你会收到一个运行时警告。只在某些特殊场景中你可能才需要用到“可写”的属性,你可以通过同时提供 getter 和 setter 来创建:

<script setup>
import { ref, computed } from 'vue'

const firstName = ref('John')
const lastName = ref('Doe')

const fullName = computed({
  // getter
  get() {
    return firstName.value + ' ' + lastName.value
  },
  // setter
  set(newValue) {
    // 注意:我们这里使用的是解构赋值语法
    [firstName.value, lastName.value] = newValue.split(' ')
  }
})
</script>

现在当你再运行 fullName.value = ‘John Doe’ 时,setter 会被调用而 firstName 和 lastName 会随之更新。

最佳实践 ​

Getter 不应有副作用 ​

计算属性的 getter 应只做计算而没有任何其他的副作用,这一点非常重要,请务必牢记。举例来说,不要改变其他状态、在 getter 中做异步请求或者更改 DOM!一个计算属性的声明中描述的是如何根据其他值派生一个值。因此 getter 的职责应该仅为计算和返回该值。在之后的指引中我们会讨论如何使用侦听器根据其他响应式状态的变更来创建副作用。

避免直接修改计算属性值 ​

从计算属性返回的值是派生状态。可以把它看作是一个“临时快照”,每当源状态发生变化时,就会创建一个新的快照。更改快照是没有意义的,因此计算属性的返回值应该被视为只读的,并且永远不应该被更改——应该更新它所依赖的源状态以触发新的计算

以下是几个升级的实例:
(1)根据输入出版书籍数量筛选作者
(2)根据输入姓名拆分姓和名分别显示
(3)根据输入的身份证号动态获取出生日期

<script setup>
import { reactive,ref, computed } from 'vue'

const author = reactive([{
  name: 'John Doe',
  books: [
    'Vue 2 - Advanced Guide',
    'Vue 3 - Basic Guide',
    'Vue 4 - The Mystery'
  ]
},
{
  name: 'Mike',
  books: [
   'Vue 2 - Advanced Guide',
  ]
},
{
  name: 'Mike2',
  books: [
    'Vue 2 - Advanced Guide',
    'Vue 3 - Basic Guide',
    'Vue 4 - The Mystery'
  ]
}])
const firstName=ref('张')
const lasnAME=ref("三")


//根据数据值计算
const publishedBooksMessage = computed(() => {
  const returnMsg=ref('')
  for(var i=0;i<author.length;i++){
      returnMsg.value+=author[i].books.length==bookNumLimit.value?author[i].name+"、":''
  }
  returnMsg.value=returnMsg.value.substring(0,returnMsg.value.length-1)
  return returnMsg.value
})
//根据输入值获取姓和名
const fullName1=computed({
  get(){
    return firstName.value+' '+lasnAME.value
  },
  set(newValue){
    if(newValue.length>=3){
        [firstName.value,lasnAME.value]=newValue.split(' ')
    }else{
      firstName.value=''
      lasnAME.value=''
    }
   
  }
})
const idCard=ref('')
const year=ref('')
const month=ref('')
const day=ref('')
//根据身份证号计算出生日期
const birthDay=computed(() => {
  if(idCard.value.length==18){
     const  newValue=idCard.value.substring(6,14);
      year.value=newValue.substring(0,4)
      month.value=newValue.substring(4,6)
      day.value=newValue.substring(6,8)
  }else{
    return '';
  }
  return year.value+"/"+month.value+"/"+day.value

})
const selectValue=ref('')
const bookNumLimit=ref(0)

</script>

<template>
  书籍数量:<input v-model="bookNumLimit"><p>已发书籍作者:</p>
  <span>{{ publishedBooksMessage }}</span><br/>
  输入姓名:<input  v-model="fullName1" val=""><br/>
  姓:<span>{{ firstName}}</span><br/>
  名:<span>{{ lasnAME}}</span>
<br/>
身份证号:<input  v-model="idCard" ><br/>
出生年月:{{ birthDay}}
</template>

实现效果:
在这里插入图片描述
在这里插入图片描述
修改身份证号,出生年月随之修改
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Windows环境下使用SSH的开源图形化SFTP工具客户端 简介和基本使用

在Windows环境下&#xff0c;有许多开源的图形化SFTP工具客户端可以使用&#xff0c;其中比较受欢迎的是WinSCP和FileZilla。下面我将分别介绍这两个工具的基本信息和使用方法。 WinSCP WinSCP是一个Windows环境下使用的开源图形化SFTP客户端&#xff0c;它也支…

06 Qt自绘组件:Switch动画开关组件

系列文章目录 01 Qt自定义风格控件的基本原则-CSDN博客 02 从QLabel聊起&#xff1a;自定义控件扩展-图片控件-CSDN博客 03 从QLabel聊起&#xff1a;自定义控件扩展-文本控件-CSDN博客 04 自定义Button组件&#xff1a;令人抓狂的QToolButton文本图标居中问题-CSDN博客 0…

第一个 Angular 项目 - 添加服务

第一个 Angular 项目 - 添加服务 这里主要用到的内容就是 [Angular 基础] - service 服务 提到的 前置项目在 第一个 Angular 项目 - 动态页面 这里查看 想要实现的功能是简化 shopping-list 和 recipe 之间的跨组件交流 回顾一下项目的结构&#xff1a; ❯ tree src/app/…

Linux---权限管理(ACL权限、特殊位和隐藏属性)

目录 1.ACT权限 1.1什么是ACT权限 1.2ACT图解 2.操作步骤 2.1添加测试目录、用户、组&#xff0c;并将用户添加到组 2.2修改目录的所有者和所属组 2.3设定权限 2.4为临时用户分配权限 2.4.1添加临时用户 2.4.2为临时用户分配特定权限 2.4.3查看目录权限&#xff0c;注…

【C语言】详解计算机二级c语言程序题

文章目录 前言资料相关程序题 一&#xff08;字符串&#xff09;程序题 二&#xff08;数组&#xff09;程序题 三&#xff08;基础&#xff09;程序题 四&#xff08;结构体&#xff09;程序题 五&#xff08;结构体&#xff09;程序题 六&#xff08;基础&#xff09; 前言 …

无人机精准定位技术,GPS差分技术基础,RTK原理技术详解

差分GPS的基本原理 差分GPS&#xff08;Differential GPS&#xff0c;简称DGPS&#xff09;的基本原理是利用一个或多个已知精确坐标的基准站&#xff0c;与用户&#xff08;移动站&#xff09;同时接收相同的GPS卫星信号。由于GPS定位时会受到诸如卫星星历误差、卫星钟差、大…

springboot+vue项目部署配置开机自启动

1.前端部属 下载nginx解压&#xff0c;在nginx\conf下找到nginx.conf 添加如下代码 server {listen 8081;server_name localhost;charset utf-8;location / {root F:/1ceshi/dist; #前端打包路径try_files $uri $uri/ /index.html;index index.html index.htm;}l…

123 Linux C++ 系统编程2 Linux 上安装卸载程序三种方法,linux 下解压缩命令 tar介绍。kill命令,top命令,umask 命令

一 通过命令和网络直接安装 sudo apt-get update sudo apt-get update 的工作就是将自己本地 ubutun的软件列表和 aliyun 的软件列表对比&#xff0c;如不一样&#xff0c;则更新。 sudo apt-get install 软件名 真正的安装 那么这里就有一个问题了&#xff0c; 怎么从aliy…

操作系统(1)——学习导论(Ⅰ)

目录 小程一言专栏链接: [link](http://t.csdnimg.cn/6grrU) 学习导论什么是操作系统主要功能强调 操作系统历史硬件层面处理器重要特点and功能 存储器磁盘I/O设备小程常用的I/O设备及其特点 小程一言 本操作系统专栏&#xff0c;是小程在学操作系统的过程中的第一步&#xff…

STL初始---C++

STL目录 1.STL的产生原因2.STL基本概念与六大组件2.1基本概念2.2六大组件 3.STL中容器、算法、迭代器3.1容器3.2算法3.3迭代器 4.STL简单应用4.1vector存放内置数据类型4.2vector存放自定义数据类型4.3vector容器嵌套容器 1.STL的产生原因 长久以来&#xff0c;软件界一直希望…

使用代理IP技术实现爬虫同步获取和保存

概述 在网络爬虫中&#xff0c;使用代理IP技术可以有效地提高爬取数据的效率和稳定性。本文将介绍如何在爬虫中同步获取和保存数据&#xff0c;并结合代理IP技术&#xff0c;以提高爬取效率。 正文 代理IP技术是一种常用的网络爬虫技术&#xff0c;通过代理服务器转发请求&a…

MDS300-16-ASEMI电源控制柜MDS300-16

编辑&#xff1a;ll MDS300-16-ASEMI电源控制柜MDS300-16 型号&#xff1a;MDS300-16 品牌&#xff1a;ASEMI 封装&#xff1a;M25 最大重复峰值反向电压&#xff1a;1600V 最大正向平均整流电流(Vdss)&#xff1a;300A 功率(Pd)&#xff1a;大功率 芯片个数&#xff1…

记录 使用FFMPEG 笔记本摄像头推流

一、使用 FFMPEG 测试摄像头拉流显示 # 获取摄像头名称 ffmpeg -list_devices true -f dshow -i dummy# 我笔记本上的摄像头名称如下 device_pnp_\\?\usb#vid_0408&pid_1020&mi_00#6&199e90f7&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global# 使…

基于JAVA的房屋出售出租系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 房屋销售模块2.2 房屋出租模块2.3 预定意向模块2.4 交易订单模块 三、系统展示四、核心代码4.1 查询房屋求租单4.2 查询卖家的房屋求购单4.3 出租意向预定4.4 出租单支付4.5 查询买家房屋销售交易单 五、免责说明 一、摘…

vue手写卡片切换,并且点击获取到卡片信息

需求&#xff1a;做一个卡片样式的列表&#xff0c;之后有一些基本信息&#xff0c;之后卡片选中后样式不一样&#xff0c;默认选中第一个卡片&#xff0c;点击卡片后可以获取到卡片的信息 一、效果 二、关键代码 index默认重0开始,activeTable默认为0,0-0等于0&#xff0c;但…

【Flink】FlinkSQL读取hive数据(批量)

一、简介: Hive在整个数仓中扮演了非常重要的一环,我们可以使用FlinkSQL实现对hive数据的读取,方便后续的操作,本次例子为Flink1.13.6版本 二、依赖jar包准备: 官网地址如下: Overview | Apache Flink 1、我们需要准备相关的jar包到Flink安装目录的lib目录下,我们需…

PostgreSQL如何使用UUID

离线安装时&#xff0c;一般有四个包&#xff0c;都安装的话&#xff0c;只需要开启uuid的使用即可&#xff0c;如果工具包(即 postgresql11-contrib&#xff09;没有安装的话&#xff0c;需要单独安装一次&#xff0c;再进行开启。 开启UUID方法 下面介绍一下如何开启&#…

第九节HarmonyOS 常用基础组件27-Rating

1、描述 提供在给定范围内选择评分的组件。 2、接口 Rating(options?:{rating:number, indicator?:boolean}) 3、参数 参数名 参数类型 必填 描述 rating number 是 设置并接收评分值。默认值&#xff1a;0&#xff1b;取值范围[0, stars]&#xff0c;小于0取0&am…

AIGC 实战:Ollama 和 Hugging Face 是什么关系?

Ollama和 Hugging Face 之间存在着双重关系&#xff1a; 1. Ollama是 Hugging Face 开发并托管的工具&#xff1a; Ollama是一个由 Hugging Face 自行开发的开源项目。它主要用于在本地运行大型语言模型 (LLM)&#xff0c;特别是存储在 GPT 生成的统一格式 (GPT-Generated Un…

com.alibaba.nacos.api.exception.NacosException: Request nacos server failed

问题描述 安装nacos2.0以上版本&#xff0c;启动报错:com.alibaba.nacos.api.exception.NacosException: Request nacos server failed com.alibaba.nacos.api.exception.NacosException: Request nacos server failed: at com.alibaba.nacos.client.naming.remote.gprc.Nami…