推荐用 watch 监听 store 的 getter 函数或 storeToRefs 提取的响应式 ref;深度监听需加 deep: true 或用计算属性副本;全局响应用 $subscribe;简单依赖追踪可用 watchEffect。

直接监听 Store 状态变化并触发回调,关键不是“监听事件”,而是利用 Vue 的响应式系统主动追踪状态值——Store 本身不发射传统 DOM 风格的“状态变更事件”,但提供了多种可靠、语义清晰的方式让组件或逻辑对 state 变化作出反应。
用 watch 监听计算属性或 getter 函数
这是最常用也最推荐的方式,适用于 Pinia(Vue 3 主流)和 Vuex(Vue 2/3 兼容):
- 不能写 watch(store.state.count, cb) —— 因为
store.state.count是一个原始值,不是响应式引用,监听会失效 - 必须包装成函数: watch(() => store.count, (newVal, oldVal) => { /* 回调 */ })
- Pina 中可配合
storeToRefs提取响应式 ref:
const { count } = storeToRefs(useCounter());
watch(count, (v) => console.log('count changed:', v));
深度监听嵌套对象或数组内容
当你要响应对象内部字段(如 user.profile.name)或数组项赋值(如 list[0] = {...})时:
将静态 Vue 页面(index.vue)改造为动态页面(Custom.vue);稿源仅限 index.vue、其引用的 CSS 与资源路径,禁止参考仓库内其他文件。Invoke when user wants to transform a static Vue page into a dynamic data-driven page with Element UI components.
- 普通 watch 默认不触发深层变更,需显式加 deep: true
- 推荐监听 getter 函数而非整个对象:
watch(() => store.config.theme, (newTheme) => { ... }, { deep: true }); - 监听数组建议用计算属性副本避免歧义:
const listCopy = computed(() => [...store.list]);
watch(listCopy, () => { /* 安全响应增删改 */ });
跨组件或无上下文场景用 $subscribe
不依赖组件生命周期、需全局响应(如日志、权限跳转、缓存同步)时,应使用 Store 自带的订阅机制:
立即学习“前端免费学习笔记(深入)”;
- Pina 使用 store.$subscribe:
store.$subscribe((mutation, state) => {
if (mutation.type === 'SET_USER') console.log('用户已登录');
}); - Vuex 使用 store.subscribe,接收 mutation 类型和状态快照
- 这类订阅在 store 实例创建后即可注册,无需挂载到组件
用 watchEffect 自动追踪依赖
适合逻辑简单、只关心“只要 store 某个值变了就执行”的场景:
- 不需要手动写 getter,自动收集依赖:
watchEffect(() => {
document.title = `当前用户:${store.user?.name || '未登录'}`;
}); - 注意:每次响应都会重新执行整个回调,不适合含副作用或异步请求的复杂逻辑
- 无法获取旧值,如需对比新旧值,仍应选 watch

















