vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > Vue3响应式数据转回原始普通对象

Vue3响应式数据转回原始普通对象的方法详解

作者:马优晨

本文介绍了在Vue中,如何使用toRaw将响应式数据转回原始普通对象,核心应用场景包括与第三方库兼容、性能优化、避免无限递归、只读不触发响应式等,文中详细解释了响应式数据与原始数据的区别,并提供了转回原始数据的方法和注意事项,需要的朋友可以参考下

在 Vue(尤其 Vue3)里,把响应式数据(Proxy/Ref)转回原始普通对象(用 toRaw),核心是:绕开响应式代理、避免不必要更新、兼容外部系统、提升性能、防止异常

一、先搞懂:响应式 vs 原始数据

二、为什么要转成原始数据(核心场景)

1. 与第三方库/原生 API 兼容(最常见)

很多库/API 不认识 Vue 的 Proxy,直接传会报错、序列化异常或行为异常。

JSON 序列化/存储JSON.stringify 对 Proxy 可能输出异常(含内部元数据),必须转原始

const user = reactive({ name: '张三' })
// ❌ 可能输出带 __v_isReactive 等内部字段
localStorage.setItem('user', JSON.stringify(user))
// ✅ 正确:转原始再序列化
localStorage.setItem('user', JSON.stringify(toRaw(user)))

图表/地图/Three.js/D3 等外部库:它们期望纯 JS 对象,传 Proxy 会报错或性能极差

import * as d3 from 'd3'
const data = reactive([1,2,3])
d3.select('svg').selectAll('rect').data(toRaw(data)) // ✅ 必须原始

Lodash/工具函数:深层遍历/克隆时,Proxy 会触发额外依赖追踪,导致性能问题或死循环

2. 性能优化:批量/大量数据操作

超大数组/对象做循环、排序、过滤、批量修改时:

const list = reactive(Array(10000).fill(0))
const rawList = toRaw(list)
// 批量处理:只操作原始,不触发更新
for (let i = 0; i < rawList.length; i++) rawList[i] = i * 2
// 最后同步一次(可选)
list.splice(0, list.length, ...rawList)

3. 避免无限递归/循环更新

场景1:对象自引用(如树、链表、状态里存自身)

const state = reactive({ data: null })
state.data = toRaw(state) // ✅ 存原始,避免 Proxy 递归监听自己

场景2:监听/计算属性里修改自身,容易死循环;用原始数据做中间计算

4. 只读不触发响应式(调试/日志/临时计算)

打印/调试时,不想触发依赖追踪,也不想看到 Proxy(Object),想看真实数据

const form = reactive({ name: '李四' })
console.log(toRaw(form)) // { name: '李四' },干净的原始对象

临时计算、判断、缓存,不需要视图更新,用原始更安全高效

5. 提交后端/接口请求

后端只认普通 JSON,不认 Proxy;虽然多数 axios/fetch 能自动处理,但转原始更稳妥、避免隐式问题

const params = reactive({ id: 1, name: 'xxx' })
axios.post('/api', toRaw(params)) // ✅ 更干净

6. 规避响应式副作用

三、怎么转:Vue3 核心 API

import { reactive, ref, toRaw } from 'vue'

// 1. reactive 对象 → 原始
const user = reactive({ name: '张三' })
const rawUser = toRaw(user) // 普通对象

// 2. ref 对象 → 原始(先取 .value)
const count = ref(0)
const rawCount = toRaw(count.value) // 原始值

// 3. 只读/浅响应 → 也能转
const ro = readonly(user)
toRaw(ro) === rawUser // true

四、重要注意

  1. toRaw 只解最外层:嵌套对象如果也是响应式,依然是 Proxy,需要递归处理
  2. 修改原始会同步到响应式:原始与响应式指向同一块内存,改原始会改数据,但不触发更新
  3. 不要替换响应式对象user = rawUser 会丢失响应式,应修改属性或用 Object.assign
  4. Vue2 不同:Vue2 用 Object.defineProperty,无 toRaw,一般用 JSON.parse(JSON.stringify(obj)) 深拷贝转普通对象

五、一句话总结

需要转原始数据,本质是:当你要和 Vue 响应式系统“脱钩”时——和外部交互、大量计算、避免递归、只看不更、性能敏感,就用 toRaw 拿原始数据。

以上就是Vue3响应式数据转回原始普通对象的方法详解的详细内容,更多关于Vue3响应式数据转回原始普通对象的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文