深层嵌套对象持久化需先toRaw剥离响应式再序列化,读取后用reactive/ref重建响应式;推荐封装useStorage Hook自动处理序列化、存储与响应式恢复。

深层嵌套对象的持久化存储,核心在于“序列化前剥离响应式代理,反序列化后重新建立响应式”。Vue 3 的 ref 和 reactive 对象在 JSON.stringify 时会丢失数据(返回空对象或报错),根本原因是 Proxy 代理无法被原生 JSON 处理。
手动剥离响应式再序列化
使用 toRaw() 获取原始对象,再 JSON 序列化。适用于已知结构、嵌套不极深的场景:
- 对顶层 ref:用
toRaw(unref(myRef)) - 对 reactive 对象:直接
toRaw(obj) - 注意:toRaw 不递归处理嵌套的 reactive/ref,需配合遍历工具(如 lodash 的
cloneDeep预处理)
使用 markRaw + 自定义序列化逻辑
对明确不需要响应式的字段(如第三方类实例、DOM 节点、或仅作配置的数据),用 markRaw() 标记,避免被 proxy 包裹;再配合自定义 replacer 函数过滤掉不可序列化的属性:
使用约定式提交(Conventional Commits)生成标准化的 Git 提交信息。适用于以下场景: (1) 暂存更改时需要提交信息; (2) 审查 diff 时希望获得结构化摘要; (3) 编写 PR 描述或变更日志(changelog)条目; (4) 用户明确要求“为本次更改编写提交信息”。 该功能会分析已暂存/未暂存的 diff,并生成按类型(type)划分范围的提交信息。
- 例如:
JSON.stringify(obj, (key, val) => typeof val === 'function' ? undefined : val) - 可封装为工具函数,自动跳过 Symbol、undefined、函数、Proxy 实例等
持久化后重建响应式结构
从 localStorage 或 IndexedDB 读取 JSON 字符串后,不能直接赋值给 reactive/ref —— 否则新对象无响应性。应:
- 用
Object.assign()或展开运算符合并到现有响应式对象中(适合浅层) - 对深层还原,推荐使用
lodash.set()或手写递归赋值,再用proxyRefs/shallowRef按需包装关键层级 - 更稳妥的方式:用
ref(JSON.parse(str))创建新 ref,再通过watch或事件触发 UI 更新
推荐方案:封装成可复用的响应式持久化 Hook
例如 useStorage(ref, key, { serializer, deserializer }),内部自动完成:
- 写入时:toRaw → 序列化 → 存 localStorage
- 读取时:解析 JSON → 用 reactive() 或 ref() 包装 → 同步到目标响应式变量
- 支持 deep watch,变更时自动保存(可节流防频繁写入)










