vue3 响应式 API:computed()

介绍

  • 基本概念
    • computed()接收一个 getter 函数或者一个包含 gettersetter 函数的对象作为参数,并返回一个基于原始响应式数据计算得到的新的响应式数据对象。
    • 计算属性的值会根据其依赖的响应式数据自动更新,当依赖的数据发生变化时,计算属性的值也会自动重新计算。
  • 返回值
    • 返回一个计算属性的响应式引用对象,可以通过.value属性来访问计算属性的值。
  • 特点
    • 自动更新:计算属性会根据其依赖的响应式数据自动更新,无需手动触发更新。
    • 缓存结果:计算属性会缓存其计算结果,只有当依赖的数据发生变化时才会重新计算。

示例

创建一个只读的计算属性

<template>
  <div>
    <div>姓名:<input type="text" v-model="name"></div>
    <div>年龄:<input type="number" v-model="age"></div>
    <div>信息:{{ info }}</div>
  </div>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue';

let name = ref('张三')
let age = ref(18)

let info = computed(() => {
  return `${name.value}-${age.value}`
})

// 报错:无法为“value”赋值,因为它是只读属性。
// info.value = name.value
</script>

在这个例子中,当name.valueage.value 发生改变时,info的值会自动重新计算。
计算属性 info只读的。

创建一个可写的计算属性

在 Vue 3 中,使用computed创建的计算属性默认情况下是只读的,只有明确提供了set方法时,它才是可写的。

示例:

<template>
  <div>
    <div>姓名:<input type="text" v-model="name"></div>
    <div>年龄:<input type="number" v-model="age"></div>
    <!-- 在input中修改info,只能触发计算属性info的setter函数。 -->
    <!-- 计算属性info本身的值是没有改变的。 -->
    <div>信息:<input type="text" v-model="info"></div>

  </div>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue';

let name = ref('张三')
let age = ref(18)

let info = computed({
  get: () => `${name.value}-${age.value}`,
  set: newValue => {
    // setVal 是用户写入的计算属性的值
    // 如果需要处理 set 逻辑,可以在这里添加代码
  }
})
</script>

这里创建了一个可写的计算属性 info ,它的 getter 函数根据nameage的值返回一个自我介绍,setter 函数则根据传入的值更新info的值。

注意:操作<input type="text" v-model="info">修改info的值,实际上只是触发了计算属性infoset方法调用。计算属性info本身的值是没有任何改变的。

set方法中直接修改计算属性本身是不正确的,会导致无限循环:

let info = computed({
  get: () => `我是${name.value},今年${age.value}`,
  set: newValue=> {
    // newValue是用户写入的计算属性的值
    // 在计算属性的set方法中,直接修改计算属性本身
    info.value = newValue
  }
})

在计算属性的set方法中,直接修改计算属性本身,不会触发数据的双向绑定:
在这里插入图片描述
浏览器控制台输出错误:

Uncaught RangeError: Maximum call stack size exceeded...

在这里插入图片描述

要实现双向绑定的效果,应该在 set 方法中修改计算属性所依赖的响应式数据源:

let info = computed({
  get: () => `${name.value}-${age.value}`,
  set: newValue => {
    // newValue 是用户写入的计算属性的值
    const [newName, newAge] = newValue.split('-')
    name.value = newName
    age.value = Number(newAge)
  }
})

当修改info的值时,set方法则根据传入的值(newValue)会正确地更新nameageget方法根据nameage的值自动更新info的值,从而实现双向绑定的效果。

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值