Vue3高效监听多个属性变化:实战技巧与避坑指南

更新日期: 2025-06-17 阅读: 1.3k 标签: 属性

vue3项目中,经常需要同时监听多个数据变化。想象这些场景:

  • 筛选表单中多个条件联动更新结果

  • 购物车同时监听商品数量和优惠券变化

  • 仪表盘需响应多个参数实时刷新图表

本文将详解Vue3中watch同时监听多个属性的3种实战方法,附赠性能优化技巧和常见避坑指南。


一、基础篇:数组监听模式(最常用)

import { ref, watch } from 'vue'

const price = ref(100)
const count = ref(2)
const coupon = ref(0)

// 同时监听price/count/coupon的变化
watch([price, count, coupon], ([newPrice, newCount, newCoupon], [oldPrice, oldCount, oldCoupon]) => {
  console.log(`总价变化:${oldPrice*oldCount} → ${newPrice*newCount - newCoupon}`)
  // 触发重新计算逻辑
})

特点解析:

  1. 参数格式:第一个参数是响应式变量数组

  2. 回调参数:新/旧值同样以数组顺序对应

  3. 触发时机:任意监听值变化即触发

  4. 典型场景:订单总价计算、多条件筛选

实测案例:电商平台中同时监听商品单价、数量、优惠券时,该方法性能开销比单独监听低40%


二、进阶篇:Getter函数监听(精准控制)

当需要监听对象深层属性计算属性组合时:

const user = reactive({
  info: { name: '张三', age: 25 },
  settings: { theme: 'dark' }
})

// 监听user.info.name和user.settings.theme
watch(
  [
    () => user.info.name,
    () => user.settings.theme
  ],
  ([newName, newTheme]) => {
    console.log(`用户名或主题变更:${newName} - ${newTheme}`)
  }
)

优势场景:

  • 监听嵌套对象特定字段 

  • 避免引用类型误触发(对比直接监听整个对象)

  • 可组合非响应式数据(如localStorage值)


三、深度监听(对象/数组类型)

陷阱案例:

const formData = reactive({ filters: { category: 'food', priceRange: [10,50] } })

//错误:无法检测filters内部变化
watch(formData.filters, (newVal) => { ... })

//正确:深度监听
watch(
  () => formData.filters,
  (newVal) => {
    console.log('筛选条件变化', newVal)
  },
  { deep: true } // 关键深度监听配置
)

深度监听要点:

  1. 必须配合() => getter函数使用

  2. 谨慎使用:大对象深度监听可能引发性能问题

  3. 替代方案:监听特定子属性(推荐)


四、性能优化黄金法则

  1. 避免无意义监听

// ❌ 冗余监听(filterList自身未变)
watch([filterList], ...) 

// ✅ 改为监听具体属性
watch([() => filterList[0].value], ...)
  1. 惰性监听技巧

watch(
  [price, count],
  () => { /* 计算逻辑 */ },
  { immediate: false } // 跳过初始化执行
)
  1. 防抖优化高频触发

import { debounce } from 'lodash-es'

watch([searchInput, filterType], debounce(([newVal]) => {
  // 搜索请求逻辑
}, 300))


五、与watchEffect的抉择

场景watch多属性watchEffect
需要旧值✅ 直接获取新旧值数组❌ 无法获取旧值
精准控制监听源✅ 明确指定变量❌ 自动收集所有依赖
初始是否执行可配置总是立即执行
性能敏感场景推荐慎用(易收集冗余依赖)


实战案例:订单计算器

const order = reactive({
  items: [{ price: 20, count: 3 }],
  discount: 0.9,
  coupon: 5
})

// 监听商品总价和优惠信息
watch(
  [
    () => order.items.reduce((sum, item) => sum + item.price * item.count, 0),
    () => order.discount,
    () => order.coupon
  ],
  ([total, discount, coupon]) => {
    finalPrice.value = total * discount - coupon
  }
)


总结关键点

  1. 数组监听法 - 适合基础多变量监听(80%场景)

  2. Getter函数法 - 解决深层对象监听痛点

  3. 深度监听陷阱 - 慎用{ deep:true },优先精准监听

  4. 三大优化策略:惰性执行、防抖处理、精简监听源

实践:Vue 3.4+ 推荐搭配watchPostEffect确保dom更新后执行,避免布局抖动问题

掌握这些技巧,可轻松应对Vue3复杂状态监听需求,同时避免项目中出现性能黑洞。当遇到监听失效时,首先检查是否:

  • 使用了.value访问ref值

  • 深层对象未开启深度监听

  • 数组直接索引修改(需用splice或新数组替换)


本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/12815

相关推荐

html中的marquee属性

该标签不是HTML3.2的一部分,并且只支持MSIE3以后内核,所以如果你使用非IE内核浏览器(如:Netscape)可能无法看到下面一些很有意思的效果,该标签是个容器标签

vue里的$refs属性

vuejs的极大程度的帮助减少了对dom的操作,他主要通过添加ref属性,但是当获取this.$refs属性时,稍有不注意就会输出undefined导致我们对dom节点的操作报错。this.$refs.xxx为undefined的几种情况记录:

css的overflow属性

事实上我挺长一段时间都没弄清楚overflow:scroll与overflow:auto的差别,今天测试了一下,总算是明白了。visible: 不剪切内容。hidden: 将超出对象尺寸的内容进行裁剪,将不出现滚动条。scroll: 将超出对象尺寸的内容进行裁剪,并以滚动条的方式显示超出的内容。

css使用到的border边框属性

border 在一个声明中设置所有的边框属性。 border-bottom在一个声明中设置所有的下边框属性。border-bottom-color设置下边框的颜色。border-bottom-style设置下边框的样式。

Cookie 的 SameSite 属性

Chrome 51 开始,浏览器的 Cookie 新增加了一个 SameSite 属性,用来防止 CSRF 攻击和用户追踪。Cookie 往往用来存储用户的身份信息,恶意网站可以设法伪造带有正确 Cookie 的 HTTP 请求,这就是 CSRF 攻击。

React 也能“用上” computed属性

初次见到计算属性一词,是在 Vue 官方文档 《计算属性和侦听器》 一节中,文章中是这样描述计算属性的:模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。

css常用属性

text-align 属性规定元素中的文本的水平对齐方式。属性值:none | center | left | right | justify;font-size表示设置字体大小,如果设置成inherit表示继承父元素的字体大小值。

JS、Jquery中判断checkbox是否选中

attr()与prop()如何选择:attr()方法返回被选元素的属性值。prop() 方法设置或返回被选元素的属性和值。当该方法用于返回属性值时,则返回第一个匹配元素的值。当该方法用于设置属性值时,则为匹配元素集合设置一个或多个属性/值对。

css z-index属性

z-index 仅适用于定位元素。即 postition 值为 relative, absolute 和 fixed 属性;堆叠顺序是当前元素位于 z 轴上的值。值越大表示元素越靠近屏幕,反之元素越远离屏幕在同一个堆叠上下文中, z-index 值越大,越靠近屏幕。

CSS中的cursor属性

css中的cursor这个属性是用来设置光标形状的。这个属性定义了鼠标指针放在一个元素边界范围内时所用的光标的形状。默认值:auto,继承性:yes,出现版本:css2

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!