Vue监听对象指定属性变化加载数据的最优方案咨询
方案推荐
优先选择监听参数组合的方案,这是Vue针对这类多依赖触发场景的最优实现,完美规避你提到的两个缺陷:
export default { props: { product: { type: Object, default: () => {}, }, }, watch: { // Vue 3支持数组形式多依赖监听 ['product.p1', 'product.p2']() { this.loadData() }, // Vue 2兼容写法 // [() => [this.product.p1, this.product.p2]] (newVal, oldVal) { // if (newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1]) { // this.loadData() // } // } }, methods: { loadData() { doApiRequest(this.product.p1, this.product.p2) } }, }
这个方案的优势:
- 不需要监听整个
product对象,不会因为其他无关属性变更触发请求,没有额外的递归监听性能开销 - 不管
p1、p2是同时变更还是分别变更,同一个事件循环内的多次依赖变更只会触发一次 watch 回调,不会重复发请求 - 不需要序列化对比,也没有额外延迟,性能最优
两种提到的方案对比
- 防抖方案
是合理的补充方案,但不是必选:- 适用场景:如果
p1/p2会有高频连续变更(比如和用户输入框绑定,打字过程中会连续修改值),可以给loadData加100-300ms的防抖,进一步合并不必要的请求 - 缺点:平白新增请求延迟,没有高频变更场景时没必要使用,也不能从根源上解决重复触发的问题,只是做了后置合并
- 适用场景:如果
- 全量监听
product+序列化对比方案
不推荐,缺陷明显:- 要监听整个
product对象需要开启deep: true,如果product属性很多,递归监听的性能开销更大 - 序列化本身有性能损耗,要是
p1/p2是复杂对象/函数/循环引用,还会出现序列化异常的问题 - 逻辑冗余,明明只需要关注两个属性,不需要额外监听整个对象
- 要监听整个
内容的提问来源于stack exchange,提问作者venom
相关产品推荐
相关产品推荐

