Nuxt3中如何监听Pinia状态里localStorage的nuxt-color-mode变化?
问题解决步骤
1. 修复Pinia仓库(推荐组合式写法)
你的核心错误在于:Pinia的仓库初始化逻辑不能直接用async,且localStorage是客户端专属API,Nuxt3服务端渲染时直接调用会报错,必须限定在客户端环境执行。同时要监听localStorage的外部修改(比如nuxt-color-mode插件直接修改),确保仓库状态同步。
修改后的~/stores/colorTheme.ts:
import { defineStore } from "pinia"; import { ref, onMounted } from 'vue'; export const useColorThemeStore = defineStore('colorThemeStore', () => { // 服务端初始化默认值,客户端读取localStorage const mode = ref<string | null>(process.client ? localStorage.getItem('nuxt-color-mode') : 'light'); // 同步localStorage到仓库状态的方法 const syncMode = () => { const newMode = localStorage.getItem('nuxt-color-mode'); if (newMode !== mode.value) { mode.value = newMode; } }; onMounted(() => { // 客户端挂载后,监听localStorage的全局变化 window.addEventListener('storage', syncMode); // 初始化时再同步一次,确保状态准确 syncMode(); }); // 组件卸载时移除监听,避免内存泄漏 const removeListener = () => { window.removeEventListener('storage', syncMode); }; return { mode, removeListener }; });
如果用选项式写法:
import { defineStore } from "pinia"; export const useColorThemeStore = defineStore('colorThemeStore', { state: () => ({ mode: process.client ? localStorage.getItem('nuxt-color-mode') : 'light' }), actions: { syncMode() { const newMode = localStorage.getItem('nuxt-color-mode'); if (newMode !== this.mode) { this.mode = newMode; } }, setupListener() { if (process.client) { window.addEventListener('storage', () => this.syncMode()); this.syncMode(); } } } });
2. 组件中正确使用仓库并监听变化
你之前的组件代码错误地将仓库实例直接赋值给mode,正确做法是先获取仓库实例,再访问其内部的mode状态并监听。
修改后的~/component/Portfolio.vue:
<script setup lang="ts"> import { useColorThemeStore } from '~/stores/colorTheme'; import { watch, onMounted, onUnmounted } from 'vue'; // 获取仓库实例 const colorStore = useColorThemeStore(); // 如果用选项式仓库,挂载时启动监听 // onMounted(() => { // colorStore.setupListener(); // }); // 监听mode状态变化,immediate设为true会立即执行一次初始值 watch(() => colorStore.mode, (newMode) => { console.log('Mode = ', newMode); }, { immediate: true }); // 如果用组合式仓库,卸载时移除监听 onUnmounted(() => { colorStore.removeListener(); }); </script>
关键错误点总结
- 禁止仓库初始化用async:Pinia的state初始化和setup函数不支持直接异步逻辑,必须在客户端挂载后通过
onMounted处理。 - 服务端环境判断:Nuxt3是SSR框架,服务端无
localStorage,必须用process.client限定客户端执行逻辑,避免报错。 - 组件获取仓库方式错误:
useColorThemeStore()返回的是仓库实例,需通过实例访问store.mode,而非直接赋值。 - 监听localStorage全局变化:
nuxt-color-mode可能直接修改localStorage,需监听storage事件同步仓库状态,否则仓库无法感知外部修改。
内容的提问来源于stack exchange,提问作者Mukhtar
相关产品推荐
相关产品推荐

