watcheffect 可自动监听页码、搜索、分类等响应式变量变化并触发分页请求,首次挂载即执行,支持数据拼接、loading 控制、abortcontroller 取消旧请求及路由 query 动态分页。

用 watchEffect 自动加载分页列表,核心是让“页码变化”和“参数变化”自然触发请求,同时保持 loading、错误、数据拼接等状态可控。它比手动 watch 更简洁,尤其适合多依赖联动的分页场景(比如带搜索 + 分类 + 页码)。
监听分页关键变量,自动触发请求
把 page、limit、searchKey、categoryId 等响应式值直接写在 watchEffect 回调里,Vue 会自动追踪它们的变化:
- ✅ 正确写法:在回调内实时读取
page.value、search.value、route.query.category等 —— 这些都会被自动纳入依赖 - ❌ 错误写法:提前解构为普通变量,例如
const p = page.value,再用p发请求 —— 这样 watchEffect 就感知不到变化 - 首次挂载时会立即执行一次,相当于自动触发第一页加载,无需额外调用
onMounted
处理分页数据追加与状态控制
watchEffect 是同步注册、异步执行,非常适合封装“请求 → 更新数据 → 控制 loading”的完整流程:
- 开头设
loading.value = true,结尾用finally关闭,避免遗漏 - 对“无限滚动”或“下拉加载更多”,可判断是否为新页(如
page.value > 1),决定是替换还是拼接数据:list.value = page.value === 1 ? res.data : [...list.value, ...res.data] - 若接口返回 total 或 hasMore,可同步更新
hasMore.value = res.hasMore,用于禁用加载按钮
防抖与请求取消(避免快速翻页导致混乱)
用户频繁点击页码或滚动时,旧请求可能还没结束,新请求已发出。用 onInvalidate 配合 AbortController 可安全取消上一轮:
- 每次执行前新建
const controller = new AbortController() - 传入
{ signal: controller.signal }到 fetch 或 axios - 在
onInvalidate中调用controller.abort(),确保旧请求不干扰新结果 - 注意:不要在
onInvalidate里操作响应式状态(如loading.value = false),它只用于清理
配合路由参数实现动态分页(如 /list?page=2&cat=3)
如果分页由 URL query 控制(比如 /products?page=3&sort=price),直接监听 route.query.page 和 route.query.sort 即可:
- 使用
useRoute()获取 route 对象 - 在 watchEffect 内读取
route.query.page和route.query.sort,无需手动 watch - 当用户手动修改地址栏或点击分页链接,watchEffect 自动重跑,数据实时同步
- query 值为字符串,记得转换类型:
parseInt(route.query.page) || 1
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










