刷刷题41(高阶watch监听面试题)

1. 响应式系统底层机制

Vue 的 watch 在内部是如何实现 ‌依赖收集‌ 的?当监听一个复杂对象(如嵌套对象或数组)时,为什么修改其内部属性有时不会触发回调?

  • 依赖收集机制 ‌:

    Vue 通过 ‌响应式代理 ‌(如 Object.definePropertyProxy)在访问被监听属性时触发 getter,将当前 watch 的回调函数注册为依赖。当依赖变化时,触发 setter 通知更新。

  • 复杂对象更新的问题 ‌:

    直接修改嵌套对象属性(如 obj.a.b = 1)或数组元素(如 arr = 1)时:

    • Vue 2 中,若未使用 Vue.setthis.$set,可能因未触发 setter 导致更新未被检测到。
    • Vue 3 使用 Proxy 可自动检测深层变化,但需确保监听时启用 deep: true

2. 性能优化:惰性监听

如何实现一个 ‌惰性监听器‌(仅在数据变化且满足特定条件时触发回调)?例如,当数值超过 100 时才执行操作。

javascript 复制代码
// Vue 3 组合式 API
import { watch, ref } from 'vue';

const value = ref(0);
watch(value, (newVal, oldVal) => {
  if (newVal > 100) {
    console.log('数值超过阈值', newVal);
  }
});

3. 调试与错误处理

watch 的回调函数抛出错误时,如何确保应用不崩溃并捕获错误?如何调试一个不触发的 watch

错误捕获‌:

javascript 复制代码
// 在回调内部使用 try/catch
watch(data, async (newVal) => {
  try {
    await fetchData(newVal);
  } catch (e) {
    console.error('捕获错误:', e);
    // 可选:上报错误到监控系统
  }
});

‌**调试不触发的 watch**‌:

  1. 检查监听的数据是否是 ‌响应式对象 ‌(如 ref/reactive)。
  2. 使用 Vue Devtools 查看响应式依赖关系。
  3. 在回调内添加 console.log 确认是否被调用。
  4. 确认是否因 ‌异步更新队列 ‌ 导致延迟(用 nextTick 验证)。

4. effect副作用

Vue 3 的 watch 如何通过 ‌Effect 副作用机制 ‌ 实现依赖追踪?当监听一个由 reactive() 创建的响应式对象时,修改其深层属性是否会触发回调?为什么?‌

  • 依赖追踪机制 ‌:

    Vue 3 通过 Proxy 代理对象的属性访问,在 watch 回调执行时,自动记录所有被访问的响应式属性,形成 ‌依赖关系图‌。当依赖项变化时,触发调度器执行回调。

  • 深层属性修改 ‌:

    默认情况下,watch 仅监听对象引用的变化(浅层监听)。若需监听深层变化,必须显式设置 { deep: true },此时 Vue 会递归遍历对象属性以建立依赖‌。

5. watch串行监听

如何实现 ‌串行异步监听‌?例如,先监听用户ID变化加载用户信息,再监听用户信息中的角色ID变化加载权限数据。‌

答案‌:

scss 复制代码
// Vue 3 Composition API
const userId = ref(0);
const userInfo = ref(null);
const permissions = ref([]);

// 第一层监听:用户ID → 用户信息
watch(userId, async (id) => {
  userInfo.value = await fetchUser(id);
}, { immediate: true });

// 第二层监听:用户信息 → 权限数据
watch(() => userInfo.value?.roleId, async (roleId) => {
  if (roleId) permissions.value = await fetchPermissions(roleId);
});

其他

  1. 内存泄漏场景 ‌:

    若在 watch 回调中注册全局事件(如 window.addEventListener),如何避免组件销毁时内存泄漏?

    • :使用 onCleanup(Vue 3)或手动在 beforeUnmount 中移除监听‌。
  2. 响应式数据类型 ‌:

    如何监听一个 MapSet 类型数据的变化?

    • :Vue 3 中需使用 reactive() 包裹,并设置 deep: true‌。
  3. 性能优化 ‌:如何避免深度监听(deep: true)导致的内存泄漏?

    • :改用特定路径监听(如 'obj.a.b'),或用计算属性返回需要监听的子属性。
  4. 与 React 的 useEffect 对比 ‌:Vue 的 watch 和 React 的 useEffect 设计哲学有何异同?

    • useEffect 依赖需显式声明,而 watchEffect 自动追踪;Vue 的响应式系统更强调细粒度依赖。
相关推荐
前端开发与ui设计的老司机10 分钟前
UI前端与数字孪生结合实践探索:智慧物流的货物追踪与配送优化
前端·ui
全能打工人12 分钟前
前端查询条件加密传输方案(SM2加解密)
前端·sm2前端加密
海天胜景34 分钟前
vue3 获取选中的el-table行数据
javascript·vue.js·elementui
翻滚吧键盘1 小时前
vue绑定一个返回对象的计算属性
前端·javascript·vue.js
秃了也弱了。1 小时前
Chrome谷歌浏览器插件ModHeader,修改请求头,开发神器
前端·chrome
乆夨(jiuze)2 小时前
记录H5内嵌到flutter App的一个问题,引发后面使用fastClick,引发后面input输入框单击无效问题。。。
前端·javascript·vue.js
忧郁的蛋~2 小时前
HTML表格导出为Excel文件的实现方案
前端·html·excel
小彭努力中2 小时前
141.在 Vue 3 中使用 OpenLayers Link 交互:把地图中心点 / 缩放级别 / 旋转角度实时写进 URL,并同步解析显示
前端·javascript·vue.js·交互
然我2 小时前
别再只用 base64!HTML5 的 Blob 才是二进制处理的王者,面试常考
前端·面试·html
NanLing2 小时前
【纯前端推理】纯端侧 AI 对象检测:用浏览器就能跑的深度学习模型
前端