明天的明天 永远的永远 未知的一切 我与你一起承担 ??

是非成败转头空 青山依旧在 几度夕阳红 。。。
  博客园  :: 首页  :: 管理

一个watch让页面卡成PPT?

Posted on 2025-11-06 16:41  且行且思  阅读(5)  评论(0)    收藏  举报

watch使用不当,轻则内存占用飙升,重则页面卡顿、响应延迟。尤其在监听大型嵌套对象时,滥用deep: true会触发全量遍历,造成严重的性能损耗。

根本问题在于:只要对象内部任意层级的属性发生变化,无论是否相关,都会执行回调。这种“无差别监听”在高频更新场景下极易拖垮应用。


方案一:精准监听,直击目标字段

避免监听整个对象,改为追踪具体路径:

watch(
  () => state.config.user.settings.theme,
  (newTheme) => {
    applyTheme(newTheme);
  }
)

仅当目标属性变化时触发,彻底规避深度遍历开销。


方案二:借助computed收敛依赖

将需监听的多个字段聚合为一个计算状态:

const userInfo = computed(() => ({
  username: state.profile.name,
  level: state.profile.level
}))

watch(
  userInfo,
  ({ username, level }) => {
    updateBadge(username, level);
  }
)

虽然监听仍需deep,但依赖范围被严格限定,极大降低遍历成本。


方案三:多源监听,显式声明依赖

使用数组形式同时监听多个响应式路径:

watch(
  [
    () => form.data.password,
    () => form.data.confirmPassword
  ],
  ([pwd, confirm]) => {
    validatePassword(pwd, confirm);
  }
)

无需开启deep,无递归遍历,性能最优,适合关联性弱但需统一处理的字段。


总结

策略优势注意点
精准监听 零遍历,最高性能 仅适用于单一路径
computed聚合 逻辑集中,依赖明确 需配合deep,但范围可控
多源监听 语法清晰,无需deep 适合多个独立字段

核心原则:拒绝全量扫描,监听粒度越细越好。
deep: true不是银弹,盲目使用只会让应用越来越慢。