在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}`)
// 触发重新计算逻辑
})
特点解析:
参数格式:第一个参数是响应式变量数组
回调参数:新/旧值同样以数组顺序对应
触发时机:任意监听值变化即触发
典型场景:订单总价计算、多条件筛选
实测案例:电商平台中同时监听商品单价、数量、优惠券时,该方法性能开销比单独监听低40%
当需要监听对象深层属性或计算属性组合时:
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 } // 关键深度监听配置
)
深度监听要点:
必须配合() => getter函数使用
谨慎使用:大对象深度监听可能引发性能问题
替代方案:监听特定子属性(推荐)
避免无意义监听
// ❌ 冗余监听(filterList自身未变)
watch([filterList], ...)
// ✅ 改为监听具体属性
watch([() => filterList[0].value], ...)
惰性监听技巧
watch(
[price, count],
() => { /* 计算逻辑 */ },
{ immediate: false } // 跳过初始化执行
)
防抖优化高频触发
import { debounce } from 'lodash-es'
watch([searchInput, filterType], debounce(([newVal]) => {
// 搜索请求逻辑
}, 300))
场景 | 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
}
)
数组监听法 - 适合基础多变量监听(80%场景)
Getter函数法 - 解决深层对象监听痛点
深度监听陷阱 - 慎用{ deep:true },优先精准监听
三大优化策略:惰性执行、防抖处理、精简监听源
实践:Vue 3.4+ 推荐搭配watchPostEffect确保dom更新后执行,避免布局抖动问题
掌握这些技巧,可轻松应对Vue3复杂状态监听需求,同时避免项目中出现性能黑洞。当遇到监听失效时,首先检查是否:
使用了.value访问ref值
深层对象未开启深度监听
数组直接索引修改(需用splice或新数组替换)
display:none;会让元素完全从渲染树中消失,渲染的时候不占据任何空间;visibility: hidden;不会让元素从渲染树消失,渲染师元素继续占据空间,只是内容不可见,display: none;是非继承属性,子孙节点消失由于元素从渲染树消失造成,通过修改子孙节点属性无法显示;
元素宽高width,min-width,max-width等元素宽度设置百分比,以包含块的宽度为标准进行计算;height,min-height,max-height等元素宽度设置百分比,以包含块的高度为标准进行计算;
readonly 只对 <input> 和 <textarea> 标签有效;disabled 对所有表单元素都有效, 包括:<input>, <textarea>, <button>, <label>, <option>, <select>等
事实上我挺长一段时间都没弄清楚overflow:scroll与overflow:auto的差别,今天测试了一下,总算是明白了。visible: 不剪切内容。hidden: 将超出对象尺寸的内容进行裁剪,将不出现滚动条。scroll: 将超出对象尺寸的内容进行裁剪,并以滚动条的方式显示超出的内容。
这篇文章主要介绍了Vue Prop属性功能与用法,结合实例形式较为详细的分析了vue.js中Prop属性的功能、原理、使用方法及相关操作注意事项,写的十分的全面细致,具有一定的参考价值
层叠顺序的大小比较;层叠顺序级别高的元素覆盖级别低的元素。首先要注意,z-index:auto 虽然可以看作z-index:0 ,但是这仅仅是在层叠顺序的比较上;从层叠上下文上讲,二者有本质差别:auto 不会创建层叠上下文,z-index:0 会创建层叠上下文。
所有的计算属性都以函数的形式写在Vue实例中的computed选项内,最终返回计算后的结果。在一个计算属性中可以完成各种复杂的逻辑,包括运算、函数调用等,只要最终返回一个结果即可。
CSS分类目录 文本/字体/颜色 文本相关 字体相关 颜色相关 背景相关 大小/布局 大小属性 margin 外边距 padding 内边距 border 边框 position 定位 列表/表格 多列属性 可伸缩框属性 列表属性 Grid属性 Table属性 动画属性 Animation 动画属性 Transition 过渡属性
word-wrap正常来说,在一行文本中,如果出现这一行已经放不下的单词,浏览器会自动将该文字转入下一行。white-space规定段落中的文本不进行换行。
border 在一个声明中设置所有的边框属性。 border-bottom在一个声明中设置所有的下边框属性。border-bottom-color设置下边框的颜色。border-bottom-style设置下边框的样式。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!