You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将含混合字符索引数组的Vue Proxy对象转为JSON/字符串?

问题描述

我有一个object(Vue Proxy),单独打印时显示如下:

Proxy {5eda71599cdbb8: {…}}
    [[Handler]]: Object
    [[Target]]: Array(0)
        5eda71599cdbb8:
            float: "none"
            size: "small"
            src: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAA...
    [[Prototype]]: Object
        length: 0
    [[Prototype]]: Array(0)
    [[IsRevoked]]: false

但使用JSON.stringify转换该对象时,仅返回空数组:

[]

需要将该对象的全部数据(即Array(0)中的键值对)转为可传输的JSON格式,且要保持对象完整性(生产环境会包含多个数组,属于响应式存储实体)。问题根源应该是5eda71599cdbb8这类非索引型的数组键,导致数组被识别为空(长度为0)。

解决方案

方法1:手动提取数组的非索引属性

数组的非索引键不会被JSON.stringify自动遍历,我们可以手动收集这些属性,同时递归处理嵌套对象,保留原结构:

function convertReactiveArrayProxy(proxyObj) {
  // 获取Proxy的原始目标对象
  const target = proxyObj[[Symbol.toPrimitive]]('object') || proxyObj;
  // 初始化结果:数组用解构复制,对象用展开复制
  const result = Array.isArray(target) ? [...target] : {...target};
  
  // 针对数组,收集所有非数字索引的属性
  if (Array.isArray(target)) {
    Object.keys(target).forEach(key => {
      if (isNaN(Number(key))) {
        // 嵌套对象递归处理
        result[key] = typeof target[key] === 'object' && target[key] !== null 
          ? convertReactiveArrayProxy(target[key]) 
          : target[key];
      }
    });
  }
  
  return result;
}

// 使用示例
const plainData = convertReactiveArrayProxy(yourProxyObject);
const jsonStr = JSON.stringify(plainData);

方法2:结合Vue的toRaw自定义序列化

如果是Vue 3的响应式对象,先用toRaw获取原始目标对象,再通过JSON.stringify的第二个参数自定义序列化逻辑:

import { toRaw } from 'vue';

function serializeReactiveStorage(storage) {
  const rawData = toRaw(storage);
  return JSON.stringify(rawData, (key, value) => {
    if (Array.isArray(value)) {
      const arrCopy = [...value];
      // 复制数组上的所有非索引属性
      Object.keys(value).forEach(k => {
        if (isNaN(Number(k))) {
          arrCopy[k] = value[k];
        }
      });
      return arrCopy;
    }
    return value;
  });
}

// 使用示例
const jsonStr = serializeReactiveStorage(yourReactiveStorage);

方法3:重构响应式存储结构(推荐)

从根源避免问题:不要给数组添加非索引属性,改用对象+数组的组合存储,数组仅存有序数据,键值对用单独的对象存储:

// 重构后的响应式存储
const storage = reactive({
  orderedItems: [], // 存需要保持顺序的数据
  itemMap: { // 存以ID为键的对象
    '5eda71599cdbb8': { float: 'none', size: 'small', src: '...' }
  }
});

这种结构下,直接调用JSON.stringify(storage)就能正确序列化所有数据,同时符合Vue响应式数据的最佳实践。

内容的提问来源于Stack Exchange,提问作者Artur Müller Romanov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 22:01:00