当前位置: 首页 > news >正文

深入理解 Vue 3 中的计算属性与侦听器:联系、区别及与函数的对比

        摘要: 在 Vue 3 的响应式系统中,计算属性(Computed)和侦听器(Watch)是处理数据逻辑的两大核心利器。虽然它们有时可以实现相似的功能,但其设计理念和使用场景却大相径庭。本文将深入剖析计算属性与侦听器的联系与核心区别,并进一步探讨它们与普通方法(Function)的不同,帮助你如何在项目中做出最合适的选择。

一、计算属性(Computed)

计算属性,顾名思义,是基于它们依赖的响应式数据动态计算得出的值。

1.1 核心特性

  • 声明式依赖追踪: 计算属性会自动追踪其内部使用的所有响应式依赖。只有当依赖发生变化时,它才会重新计算。这是一种“惰性求值”的机制。

  • 缓存机制: 这是计算属性最核心的优势。只要依赖项没有变化,多次访问计算属性会立即返回之前缓存的结果,而不会重新执行函数。

  • 返回值: 计算属性必须返回一个值,并且这个值可以被用在模板中,就像普通的 data 属性一样。

1.2 语法(Composition API)

在 Vue 3 的 Composition API 中,我们使用 computed 函数。

import { ref, computed } from 'vue';const firstName = ref('张');
const lastName = ref('三');// 写法一:传入一个 getter 函数
const fullName = computed(() => {console.log('计算属性 fullName 被重新计算了!');return `${firstName.value} ${lastName.value}`;
});// 写法二:使用包含 get 和 set 函数的对象(可写计算属性)
const writableFullName = computed({get() {return `${firstName.value} ${lastName.value}`;},set(newValue) {[firstName.value, lastName.value] = newValue.split(' ');}
});

二、侦听器(Watch)

侦听器用于观察和响应特定数据源的变化,并在变化时执行副作用(Side Effects)。

2.1 核心特性

  • 副作用处理: 侦听器的核心目的是执行副作用,例如:发起异步请求、操作 DOM、更改其他状态等。

  • 无返回值: 侦听器函数不返回任何值,它的价值在于执行过程,而非产生一个新值。

  • 更底层、更灵活: 它可以监听一个或多个数据源,并获取变化前后的值,让你能够执行任何复杂的逻辑。

2.2 语法(Composition API)

使用 watch 或 watchEffect 函数。

import { ref, watch, watchEffect } from 'vue';const count = ref(0);
const anotherState = ref('');// 1. watch:显式指定侦听源和回调
watch(count, (newValue, oldValue) => {console.log(`count 从 ${oldValue} 变更为 ${newValue}`);// 可以在这里发起 Ajax 请求,或者做其他任何事情
});// 监听多个源
watch([count, anotherState], ([newCount, newState], [oldCount, oldState]) => {// 处理逻辑
});// 2. watchEffect:自动追踪其同步执行过程中的依赖
watchEffect(() => {console.log(`count 的值是:${count.value}, 自动被追踪!`);// 当 count.value 变化时,这个函数会重新执行
});

三、计算属性 vs 侦听器

3.1 核心区别对比表

特性计算属性 (Computed)侦听器 (Watch)
设计目的基于依赖生成一个新的派生值在依赖变化时执行副作用
返回值必须返回一个值没有返回值
缓存有缓存,依赖不变则不重新计算无缓存,变化即执行
异步操作不支持在 getter 函数内进行异步操作支持,是处理异步操作的理想场所
使用场景模板中需要渲染的、经过复杂计算的数据数据变化时需要执行的操作(如请求API、验证)

3.2 联系与选择

联系: 它们都是 Vue 响应式系统的重要组成部分,用于响应数据变化。

如何选择?

  • 使用计算属性的场景:

    • 你需要根据一个或多个响应式数据计算出一个新值,并希望在模板中像普通属性一样使用它。

    • 你希望利用缓存来避免不必要的重复计算,优化性能。

    • 典型例子: 拼接全名、过滤列表、对数据进行格式化或排序。

  • 使用侦听器的场景:

    • 数据变化时,你需要执行异步操作(如 API 调用)。

    • 数据变化时,你需要执行一个非幂等的、有副作用的操作(如操作 DOM、更改浏览器缓存、打印日志)。

    • 你需要知道数据变化前后的具体值

    • 典型例子: 搜索框输入变化时请求搜索接口、表单验证、在 ID 变化时重新获取用户详情。

四、计算属性/侦听器 vs 方法

这是一个常见的困惑点:为什么不用一个方法来代替计算属性?

4.1 方法(Method)

方法是在被调用时才会执行的函数。它不具备响应性,也不会自动追踪依赖。

const firstName = ref('张');
const lastName = ref('三');// 一个方法
function getFullName() {console.log('方法 getFullName 被调用了!');return `${firstName.value} ${lastName.value}`;
}

在模板中调用:<div>{{ getFullName() }}</div>

4.2 与方法的主要区别

特性计算属性 / 侦听器方法 (Method)
响应性是响应式的,自动依赖追踪不是响应式的,只是一个普通函数
执行时机计算属性:依赖变化时自动重新计算(有缓存)。
侦听器:依赖变化时自动执行。
只在被调用时执行
性能计算属性有缓存,依赖未变时性能极佳每次调用都会执行,无缓存
模板中的使用计算属性在模板中作为属性使用:{{ fullName }}在模板中作为方法调用{{ getFullName() }}

4.3 示例对比:计算属性 vs 方法

假设我们在一个循环中多次使用这个值:

<!-- 使用计算属性 -->
<p>全名:{{ fullName }}</p>
<p>再次展示全名:{{ fullName }}</p>
<!-- 只要 firstName 或 lastName 不变,console 只会打印一次,第二次直接读取缓存 --><!-- 使用方法 -->
<p>全名:{{ getFullName() }}</p>
<p>再次展示全名:{{ getFullName() }}</p>
<!-- 每次渲染,两个 getFullName() 调用都会执行,console 会打印两次 -->

从这个例子可以清晰地看到,对于衍生数据,计算属性因其缓存机制而具有显著的性能优势。

http://www.dtcms.com/a/617679.html

相关文章:

  • 2.FPGA板卡通过电脑映射连接上网
  • RTCP包之SR和RR
  • 40 token
  • 如何在 Celestia 区块链上构建验证者节点的详细手册
  • Linux权限知识点
  • MySQL: 数据库读写分离与负载均衡的实现方式及深度分析
  • 红帽企业Linux:企业级开源操作系统领航者
  • 怎么做网站开发建一个电商平台多少钱
  • 人工智能技术- 语音语言- 05 GPT-4o 自然人机对话
  • HarmonyOS实用指南:harmonyos + 华为
  • 什么是Spring Boot 应用开发?
  • uniapp实现android/IOS消息推送
  • 汽车网站开发流程html5 网站开发软件
  • HarmonyOS:harmonyos从入门到落地
  • OpenCV(二十九):高通滤波-索贝尔算子
  • 幽冥大陆(二十一)go语言智慧农业电子秤读取——东方仙盟炼气期
  • 北京网站建设需要花多少钱视觉冲击力的网站设计
  • 开发板上搭建nextcloud和minio服务
  • Dubbo监控中心全解析:构建微服务可观测性的基石
  • Rust 内存优化实战指南:从字节对齐到零拷贝
  • 【数据结构】常见时间复杂度以及空间复杂度
  • 2345中国最好的网址站非凡软件站
  • C 语言希尔排序:原理、实现与性能深度解析
  • 【期末网页设计作业】HTML+CSS+JS 电影网站设计与实现 影视主题网站(附代码)
  • react 的状态管理
  • 世界上最有趣的网站外贸稳中提质韧性强
  • 简单理解:DCDC(直流 - 直流转换器)和LDO(低压差线性稳压器)
  • 电科金仓国产数据库KingBaseES深度解析:五个一体化的技术架构与实践指南
  • 2025卷【答案】
  • 防止网站被克隆买完网站怎么建设