vue2深度属性嵌套
导读
面试时被问到了如果监听一个嵌套属性很深的对象,直接使用watch可能会失效,因为Vue2的响应式系统默认是无法检测到深层嵌套属性的变化。和面试官讨论了一会儿,加上面试后问了一下DeepSeek,总结得到了可以采用的方法。
注意,以下内容,都将讨论对user.address.city
的监听
1 | export default { |
使用options配置中的deep属性。
1 | watch: { |
但这样,将导致整个user
对象的所有层级的属性都被监听,会对性能造成很大的影响。
使用属性路径指定具体的监听属性
由于watch本身支持传入属性路径,我们可以直接把user.address.city
传入。
1 | watch("user.address.city",{ |
此方法不适合动态路径。
使用Vue.set 或者this.$set
如果响应式失效,那我们就使用this.$set
确保数据是响应式的。
1 | methods:{ |
这样多了一次手动操作,繁琐一点。
使用计算属性
如果经常发生变化的,且属性嵌套深,可以使用computed做“截短”操作,生成一个新的变量,然后监听这个变量。
1 | computed:{ |
由于computed本身有lazy和记忆功能,性能会更优,但当有很多的嵌套属性都需要更新,可能会造成代码量的增多。
升级到Vue3
由于Vue3响应式变量是迭代的方式(Vue2是嵌套递归)生成,且Proxy能拦截到特定的属性,天然不会发生不必要的监听。
总结
上述方法的优缺点总结如下:
方法 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
deep: true | 监听整个对象的变化 | 简单直接 | 性能开销较大 |
监听具体属性 | 监听特定嵌套的属性 | 性能较好 | 需要明确路径,不支持动态路径 |
Vue.set | 动态属性的增加 | 确保响应式 | 代码比较繁琐 |
计算属性 | 监听特定嵌套的属性 | 逻辑清晰 | 代码较多,复杂情况下将有很多的计算属性。 |
升级到Vue3 | 可以升级的项目且升级成本较低 | 更好的响应式性能 | 需要整个版本升级,技术和时间成本较大 |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 程序员零塔的小破站!
评论