Vue3中的计算属性的详细讲解

一、Vue3计算属性基础使用

1.1. 不使用计算属性

当我们需要针对一些数据进行一些逻辑运算时可以使用模板中的表达式如下:

<script setup lang="ts">
import { reactive } from "vue";
const onePeople = reactive({
  name: "Sam Xiaoguai",
  chineseName: [
    "萨姆",
    "小乖"
  ]
});
</script>
<template>
  <div>
    {{ onePeople.chineseName.length > 0 ? "有中文名" : "没有" }}
  </div>
</template>
<style scoped></style>

但是如果在模板中写太多逻辑,会让模板变得臃肿,难以维护。因此我们可以使用计算属性computed() 方法来描述依赖响应式状态的复杂逻辑,返回值为一个计算属性 ref。

1.2. 使用计算属性

<script setup lang="ts">
import { reactive,computed } from "vue";
const onePeople = reactive({
  name: "Sam Xiaoguai",
  chineseName: [
    "萨姆",
    "小乖"
  ]
});
// 一个计算属性 ref
const haveChineseName = computed<string>(() => {
  return onePeople.chineseName.length > 0 ? "有中文名" : "没有"
})
</script>
<template>
  <div>
    {{ haveChineseName }}
  </div>
</template>
<style scoped></style>

二、计算属性VS常规方法

<script setup lang="ts">
import { reactive,computed } from "vue";
const onePeople = reactive({
  name: "Sam Xiaoguai",
  chineseName: [
    "萨姆",
    "小乖"
  ]
});
// 一个计算属性 ref
const haveChineseName = computed<string>(() => {
  return onePeople.chineseName.length > 0 ? "有中文名" : "没有"
})
function haveChineseNameFun ():string {
    return onePeople.chineseName.length > 0 ? "有中文名" : "没有"
}
</script>
<template>
  <div>
    <span>{{ haveChineseName }}</span>
    <span>{{ haveChineseName }}</span>
    <span>{{ haveChineseName }}</span>
    <span>{{ haveChineseName }}</span>
  </div>
  
  <div>
   <span>{{ haveChineseNameFun() }}</span>
   <span>{{ haveChineseNameFun() }}</span>
   <span>{{ haveChineseNameFun() }}</span>
   <span>{{ haveChineseNameFun() }}</span>
  </div>
</template>
<style scoped></style>

在模板中,分别使用了方法和计算属性四次,然而,然而,不同之处在于计算属性值会基于其响应式依赖被缓存。一个计算属性仅会在其响应式依赖更新时才重新计算。这意味着只要 onePeople不改变,无论多少次访问 haveChineseName都会立即返回先前的计算结果,而不用重复执行 getter 函数。

  • 如下:计算属性永远不会更新,因为 Date.now() 并不是一个响应式依赖

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

<script setup lang="ts">
import {  computed } from "vue";
const now = computed<number>(() => Date.now());
function nowTime(): number {
  return Date.now();
}
</script>
<template>
  <div>
    {{ now }}
  </div>
  <div>
    {{ now }}
  </div>
  <div>
    {{ now }}
  </div>
  <div>
    {{ nowTime() }}
  </div>
  <div>
    {{ nowTime() }}
  </div>
  <div>
    {{ nowTime() }}
  </div>
</template>
<style scoped></style>

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

三、可写计算属性

计算属性默认是只读的。当你尝试修改一个计算属性时,你会收到一个运行时警告。

Write operation failed: computed value is readonly

因此如果你需要用到“可写”的属性,你可以通过同时提供 getter setter 来创建

<script setup lang="ts">
import { ref, computed } from 'vue'
 
const firstName = ref('Sam')
const lastName = ref('xiaoguai')
const fullName = computed({
  // getter
  get() {
    return firstName.value + ' ' + lastName.value
  },
  // setter
  set(newValue) {
    // 注意:我们这里使用的是解构赋值语法
    [firstName.value, lastName.value] = newValue.split(' ')
  }
})
fullName.value = "sam xiaoguai"
</script>
<template>
  <div>
    {{ fullName }}
  </div>
</template>
<style scoped></style>
Vue计算属性(computed)是一种能够基于现有的响应式数据进行计算的属性。它们本质上是一个函数,但是可以像普通属性一样在模板使用。计算属性的值会根据它的依赖(响应式数据)自动进行更新,只要依赖数据发生变化,计算属性就会重新计算。 计算属性的定义方式如下: ```javascript computed: { propertyName: function() { // 计算逻辑 return value; } } ``` 其,propertyName 是计算属性的名称,function 是计算属性的定义。在这个函数,你可以编写任何逻辑来计算属性的值,并在最后使用 return 语句返回计算结果。 在模板使用计算属性的方式与使用普通属性类似。例如,如果有一个计算属性 fullName,我们可以在模板像这样使用它: ```html <p>{{ fullName }}</p> ``` 当 fullName 的依赖数据发生变化时,Vue 会自动更新模板的 fullName 值。 计算属性还有一些特殊的特性: 1. 缓存:计算属性默认是带有缓存的,也就是说,只要依赖数据没有发生变化,多次访问计算属性会立即返回之前的计算结果,而不会重新计算。这是因为 Vue 内部会追踪依赖,并在依赖发生变化时才重新计算计算属性的值。 2. Setter:除了 getter 函数,计算属性还可以定义一个 setter 函数,用于处理对计算属性的赋值操作。setter 函数接收新的值作为参数,并可以根据需要对其他相关的响应式数据进行更新。 下面是一个使用计算属性的示例: ```html <template> <div> <input v-model="firstName"> <input v-model="lastName"> <p>{{ fullName }}</p> </div> </template> <script> export default { data() { return { firstName: '', lastName: '' }; }, computed: { fullName: { get() { return this.firstName + ' ' + this.lastName; }, set(value) { const [firstName, lastName] = value.split(' '); this.firstName = firstName; this.lastName = lastName; } } } }; </script> ``` 在上面的示例,我们定义了两个输入框用于输入 firstName 和 lastName。计算属性 fullName 通过 get 函数返回 firstName 和 lastName 的拼接结果。同时,我们也定义了一个 set 函数,用于根据传入的新值更新 firstName 和 lastName 的值。 通过这样的方式,我们可以在模板双向绑定计算属性 fullName,并且在输入框输入 fullName 的值时,会自动更新 firstName 和 lastName 的值。 希望这个详细讲解对你有帮助!如果还有其他问题,请继续提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值