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

Vue3+Vite 06:计算属性 computed 与侦听器 watch

一、计算属性 computed

1. 作用

基于已有的响应式数据,派生出新的计算结果,核心特性是依赖不变则结果缓存,重复使用不会重复计算,性能优于普通方法。

适合场景:需要对数据做转换、拼接、筛选,且结果会被多次使用的场景。

2. 基础用法

计算属性默认是只读的,通过return返回计算结果。最典型的场景是拼接全名:

<template> <div> <p>姓:{{ firstName }}</p> <p>名:{{ lastName }}</p> <p>全名:{{ fullName }}</p> <button @click="changeName">修改姓氏</button> </div> </template> <script setup> import { ref, computed } from 'vue' const firstName = ref('张') const lastName = ref('三') // 计算属性:依赖两个变量,自动派生全名 const fullName = computed(() => { return firstName.value + lastName.value }) const changeName = () => { firstName.value = '李' } </script>

点击按钮修改firstName后,fullName会自动重新计算并更新页面。

3. 核心特性

计算属性和普通方法最大的区别就是缓存

  • 计算属性:只要依赖的响应式数据没有变化,多次访问只会计算一次,后续直接返回缓存结果
  • 普通方法:每调用一次就执行一次,没有缓存
<template> <div> <h3>计算属性(调用3次,仅计算1次)</h3> <p>{{ fullName }}</p> <p>{{ fullName }}</p> <p>{{ fullName }}</p> <h3>普通方法(调用3次,执行3次)</h3> <p>{{ getFullName() }}</p> <p>{{ getFullName() }}</p> <p>{{ getFullName() }}</p> </div> </template> <script setup> import { ref, computed } from 'vue' const firstName = ref('张') const lastName = ref('三') // 计算属性 const fullName = computed(() => { console.log('计算属性执行了') return firstName.value + lastName.value }) // 普通方法 const getFullName = () => { console.log('普通方法执行了') return firstName.value + lastName.value } </script>

打开控制台可以看到:计算属性只打印 1 次,普通方法打印 3 次。

4. 完整写法

计算属性默认只读,特殊场景下可以配置getset实现可写,一般用于反向修改依赖数据:

<template> <div> <p>全名:{{ fullName }}</p> <button @click="setFullName">设置全名</button> </div> </template> <script setup> import { ref, computed } from 'vue' const firstName = ref('张') const lastName = ref('三') const fullName = computed({ // 读取时触发 get() { return firstName.value + lastName.value }, // 修改时触发 set(newVal) { const arr = newVal.split('') firstName.value = arr[0] lastName.value = arr.slice(1).join('') } }) const setFullName = () => { fullName.value = '李四' } </script>

二、侦听器 watch

1. 作用

监听指定的响应式数据,当数据发生变化时,执行对应的回调函数。适合处理数据变化后的副作用,比如发送请求、操作 DOM、执行异步逻辑等。

2. 基础用法

监听一个ref数据,变化时触发回调,回调函数接收新值和旧值两个参数。

<template> <div> <p>计数:{{ count }}</p> <button @click="count++">+1</button> </div> </template> <script setup> import { ref, watch } from 'vue' const count = ref(0) // 监听count变化 watch(count, (newVal, oldVal) => { console.log('新值:', newVal) console.log('旧值:', oldVal) console.log('数据变化了,执行对应操作') }) </script>

3. 监听多个数据源

可以传入数组,同时监听多个数据,任意一个变化都会触发回调:

const count = ref(0) const name = ref('张三') watch([count, name], ([newCount, newName], [oldCount, oldName]) => { console.log('count或name变化了') })

4. 深度监听 deep

当监听的是对象 / 数组时,默认只能监听到整个对象的替换,监听不到内部属性的变化,需要开启deep: true开启深度监听。

注意
  • 监听reactive定义的对象:默认自动开启深度监听,无需手动加deep
  • 监听ref定义的对象:默认浅监听,必须手动加deep: true才能监听内部属性
<template> <div> <p>姓名:{{ user.name }}</p> <button @click="changeName">修改姓名</button> </div> </template> <script setup> import { ref, watch } from 'vue' const user = ref({ name: '张三', age: 20 }) // ref对象必须加deep才能监听内部属性变化 watch(user, (newVal) => { console.log('用户信息变化了', newVal) }, { deep: true }) const changeName = () => { user.value.name = '李四' } </script>

5. 立即执行 immediate

默认watch只有数据变化时才触发,加上immediate: true后,页面初始化时就会立即执行一次回调

watch(count, (newVal) => { console.log('执行了', newVal) }, { immediate: true // 初始化立即执行一次 })

6. 监听对象的单个属性

如果只需要监听对象的某一个属性,不用监听整个对象,用函数返回指定属性即可,性能更好:

const user = reactive({ name: '张三', age: 20 }) // 只监听name属性 watch(() => user.name, (newVal) => { console.log('name变化了:', newVal) })

三、computed 与 watch 对比

特性computed 计算属性watch 侦听器
核心作用派生新数据,有返回值监听数据变化,执行副作用,无返回值要求
缓存特性支持缓存,依赖不变不重新计算无缓存,数据变化就执行
异步操作不支持(必须同步返回结果)支持(发送请求、定时器等)
使用场景数据转换、拼接、筛选数据变化后发请求、操作 DOM、执行复杂逻辑

四、总结

  1. computed:用于派生新数据,自带缓存,性能优,优先用于数据转换场景
  2. watch:用于监听数据变化执行副作用,支持深度监听、立即执行,适合异步、复杂逻辑
http://www.jsqmd.com/news/1070330/

相关文章:

  • 当 AIR 只支持 Mac,我开始重新思考操作系统这件事
  • 方案设计-器件选型-BOM 降本,一款 AI 全链路搞定
  • 百考通:覆盖PLC控制、移动开发、AI/机器学习七大核心领域
  • 金蝶云星空自研凭证快速导入模板|告别官方复杂模板,一键高效导入凭证
  • QuickBMS完整指南:快速提取游戏资源的终极开源工具
  • 百胜软件「SenJent胜鉴通」正式发布丨一单一录像,让每一笔订单都有据可查
  • 为什么83%的AI项目失败源于文化断层?——深度拆解AISMM六大文化支柱与SITS 2026合规性映射表
  • QRazyBox:终极二维码修复工具,让损坏的二维码重获新生
  • 【符号定义】失败时间 x 删失事件 C
  • js-slice 和 splice 的区别
  • Linux一口气删掉近4000行代码!活了40年的苹果协议,最终竟被AI“送走”了……
  • Responses WebSocket 协议详解:为什么它会让 Agent 工作流更快
  • 解锁游戏资源宝库:QuickBMS开源工具深度解析
  • 如何在Mac上轻松运行Windows软件:Whisky跨平台兼容工具完全指南
  • 【AI模型成熟度管理黄金标准】:2026奇点大会首发ML生命周期五级评估框架(附Gartner验证数据)
  • AI工具如何真正读懂你的知识库?揭秘语义对齐失败的7个隐藏根源及实时修复方案
  • Citra模拟器终极指南:如何在PC上完美运行任天堂3DS游戏
  • 为什么92%的AI助手在知识库检索中“装懂”?深度拆解嵌入模型偏差、chunk策略失效与重排序坍塌
  • OFD转图片总踩坑?用对这3个工具,批量转JPG/长图/高清图一次搞定
  • 限流熔断双失效,请求丢失率飙升47%:企业级AI网关速率控制黄金配置清单,仅限内部技术委员会解密
  • 星露谷物语农场规划器:3步打造完美农场的可视化设计神器
  • 企业架构建模利器:ArchiMate开源工具Archi的5大核心优势
  • 3步搞定电脑内存检测:Memtest86+免费内存测试终极指南
  • 喂了海量数据却被 AI 漏掉?教你用企微数据打破大模型知识库的“向量污染”
  • SITS 2026 AI流程自动化水平白皮书核心发现(2024年唯一经CNAS认证的AISMM实证评估)
  • 国际期货主流交易品种
  • 2026永康木门十大品牌专业排名揭秘
  • 别再瞎选:AI 编码工具实战指南
  • 如何在5分钟内快速上手Zotero PDF中文翻译插件:完整指南与最佳实践
  • 星露谷物语农场规划器:可视化打造你的梦想农场