在Vue3中,如何将嵌套的代理对象(响应式数据)转换为普通对象?

7
我有一个 Pinia 商店,其中包含一个用户对象。
export const useStore = defineStore('store', {
  state: () => ({
    currentSlide: 1,
    user: {},
    data,
  }),
})

我正在将其更新为用户对象内部有一个数组vote

然后,投票数组具有多个对象作为投票...所以我将数组设置为 user.vote,它的格式为[{vote:01},{vote:02}.{vote:3}]

我需要将此数组推送到mongodb.. 但是当我尝试访问此数组时,由于它是响应式数据,因此它是一个带有多个Proxy对象的Proxy Object。

因此,我尝试了toRaw(user.vote)(不确定这是否是正确方法),数组不再是Proxy,而是常规数组..但是其中的对象(投票)仍然是Proxy对象..

如何从此Pinia结构获取常规数组和常规对象以发送到mongodb?


我发现了这个网址https://dev59.com/G8Pra4cB1Zd3GeqPkqO4并使用了structuredClone,它确实有效!但我希望能得到一些建议,是否这是正确的方法,或者是否有其他方法。 - Alim Bolar
2
调用 JSON.stringify(user.vote) 有什么问题?MongoDB 存储 JSON 值。 - IVO GELOV
1
@IVOGELOV:你说得完全正确!我想我犯了“过度思考问题”的错误……我只是假设代理对象可能是一种复杂的格式,需要一些复杂的“解密”方法……;-)……感谢您为我简化它……我需要它成为一个对象,所以我只需执行JSON.parse(JSON.stringify(user.vote)),它就完美地工作了……:-) - Alim Bolar
2个回答

3

TypeScript 版本:

import { isReactive, toRaw } from 'vue'

export function isObject (value: unknown): boolean {
  return value !== null && !Array.isArray(value) && typeof value === 'object'
}

export function getRawData<T>(data: T): T {
  return isReactive(data) ? toRaw(data) : data
}

export function toDeepRaw<T>(data: T): T {
  const rawData = getRawData<T>(data)

  for (const key in rawData) {
    const value = rawData[key]

    if (!isObject(value) && !Array.isArray(value)) {
      continue
    }

    rawData[key] = toDeepRaw<typeof value>(value)
  }

  return rawData // much better: structuredClone(rawData)
}

JavaScript 版本:

import { isReactive, toRaw } from 'vue'

export function isObject (value) {
  return value !== null && !Array.isArray(value) && typeof value === 'object'
}

export function getRawData (data) {
  return isReactive(data) ? toRaw(data) : data
}

export function toDeepRaw (data) {
  const rawData = getRawData(data)

  for (const key in rawData) {
    const value = rawData[key]

    if (!isObject(value) && !Array.isArray(value)) {
      continue
    }

    rawData[key] = toDeepRaw(value)
  }

  return rawData // much better: structuredClone(rawData)
}

使用 Nuxt.js 3,在文件中添加这些辅助函数到 utils/ 文件夹以进行自动导入。


1
如果你克隆数据并将克隆版本发送到数据库会怎样呢?这通常是我所做的:
const cloneToSendToMongoDB = JSON.parse(JSON.stringify(user.vote)
或者使用lodash的cloneDeep,比上面的方法更易读一些:
// install lodash if you don't have it
import cloneDeep from 'lodash/cloneDeep' 

const cloneToSendToMongoDB = cloneDeep(user.vote)

警告:不要过分激动并认为,噢,我们在克隆东西,所以我可以使用这个酷炫的新的structuredClone方法来做这个,不幸的是,它只能展开最外层的代理,而无法展开嵌套的代理。上面的前两种方法将展开所有内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接