Vue 3 响应式数据需手动与 localStorage 双向同步:初始化时读取赋值给 ref,变更时先更新 ref 再写入 localStorage,并通过 storage 事件监听跨标签页变化,推荐封装为 useSharedRef 组合式函数。

Vue 3 的响应式数据本身不会自动感知 localStorage 的变化,必须手动建立“读取 → 响应式绑定”和“变更 → 写入 + 广播”两个通路。核心不是让 localStorage 变响应式,而是让响应式状态与 localStorage 保持双向同步,并在跨标签页时借助 storage 事件桥接。
初始化时从 localStorage 恢复响应式状态
组件挂载时,不能只靠计算属性现场读取 localStorage(那不是响应式的),而应把值读出来,赋给 ref 或 reactive:
- 用 ref 定义状态,例如
const theme = ref(localStorage.getItem('theme') || 'light') - 或在
setup()中显式读取并赋值:theme.value = localStorage.getItem('theme') || 'light' - 若使用
customRef,可在工厂函数中封装读取逻辑,首次访问即拉取
变更时同步写入 localStorage 并更新本地响应式
仅调用 localStorage.setItem() 不会触发 Vue 更新,必须确保:写操作既落盘,又驱动响应式更新:
Vue 3 组合式 API 与 最佳实践,涵盖代码组织、useXxx 模式、组合式函数设计、Store 集成、响应式优化及功能抽取。
- 修改状态时,先改
ref.value,再调localStorage.setItem(key, JSON.stringify(value)) - 避免反向操作(如先写 localStorage 再赋值 ref),否则 watch 可能漏掉初始变更
- 高频操作(如输入框实时存)建议加防抖,localStorage 是同步阻塞 API,频繁调用影响性能
监听 storage 事件实现跨标签页同步
同一域名下其他标签页修改 localStorage 时,当前页会收到 storage 事件——这是唯一可用的跨页通知机制:
立即学习“前端免费学习笔记(深入)”;
- 全局监听:
window.addEventListener('storage', handler),注意只注册一次(如放在onBeforeMount或工具函数内) - 在 handler 中比对
event.key,匹配后用JSON.parse(event.newValue)更新对应 ref - 关键细节:当前页调用
setItem不会触发自己的storage事件,所以必须在写入前主动更新 ref(这就是“劫持”的实质)
封装成可复用的组合式函数
重复写读、写、监听逻辑容易出错,推荐抽成 useSharedRef(key, initialValue):
- 内部用
ref管理状态,构造时尝试从 localStorage 读取 - 提供
.valuesetter,拦截赋值动作:更新 ref 后立即写入 localStorage - 内部统一注册 storage 监听器,按 key 过滤,自动同步远端变更
- 支持默认值 fallback 和类型安全提示(如泛型约束为
string | number | boolean | object)

















