用 watchEffect 监听响应式 width.ref 实现断点布局自动切换:通过 ref 包裹 window.innerWidth,resize 时更新其值,watchEffect 内读取并计算 layoutMode 等状态,驱动模板渲染,避免直接操作 DOM 或重复计算。

用 watchEffect 监听 window.innerWidth,结合响应式断点逻辑,就能自动切换布局——关键不是“监听宽度”,而是“在宽度变化时精准触发更新,且避免重复计算和副作用泄漏”。
监听窗口宽度并定义断点逻辑
watchEffect 适合副作用驱动的响应式场景。它会自动追踪内部读取的响应式数据或计算属性,但 window.innerWidth 是普通值,需手动触发追踪:通过一个响应式引用(如 ref)包裹,并在 resize 事件中更新它。
- 创建
const width = ref(window.innerWidth)作为响应式宽度源 - 在
onMounted中绑定resize事件,每次更新width.value - 在
watchEffect内部读取width.value,Vue 就会自动建立依赖关系
根据宽度值动态设置布局状态
不要在 watchEffect 里直接操作 DOM 或调用复杂函数,而是聚焦于更新组件内部的状态变量(如 layoutMode),让模板基于该状态自动渲染不同布局。
- 例如定义
const layoutMode = ref('desktop') - 在
watchEffect中按断点判断:if (width.value ,依此类推 - 模板中用
v-if或:class绑定layoutMode,保持视图层纯粹
注意清理与性能边界
watchEffect 默认不自动清理副作用,而窗口 resize 频率高,必须防止内存泄漏和过度执行。
- 使用
onBeforeUnmount清理resize事件监听器 - 可加节流(如
useThrottleFn)或用requestAnimationFrame包裹 width 更新,避免每像素变动都触发 - 确保
watchEffect内部只做轻量状态赋值,避免同步触发大量重渲染或 API 请求
配合 Composition API 封装复用
把这套逻辑抽成自定义 Hook(如 useResponsiveLayout),返回 layoutMode 和断点工具方法,多个组件可共享同一套响应逻辑,也便于测试和维护。
- 返回值可包括
isMobile: computed(() => layoutMode.value === 'mobile')等语义化布尔值 - 支持传入自定义断点对象,比如
{ mobile: 480, tablet: 768, desktop: 1024 } - 内部仍用
watchEffect+ref+resize,但对外隐藏实现细节
不复杂但容易忽略:真正让布局“自动切换”的,不是监听本身,而是把宽度变化映射为清晰、可预测、可组合的状态信号——watchEffect 是那个可靠又轻量的连接器。










