Axios GET请求返回[Proxy, Proxy]问题咨询 - Flask与Vue.js场景
问题原因说明
1. Proxy是什么
Proxy是ES6内置的原生代理对象,Vue3的响应式系统完全基于Proxy实现:你在组件中声明的响应式数组/对象(用ref/reactive定义的变量),内部存储的所有值都会被自动包装为Proxy实例,用来监听数据的读写、增删操作,从而实现修改数据自动更新视图的响应式能力。
你打印出来的[Proxy, Proxy]不是Axios请求返回的结果,是Vue的响应式机制给数据套的代理层,和你的请求逻辑无关。
2. 为什么返回结果不符合预期
你代码中用JSON.parse(JSON.stringify(response.data[data]))已经把Axios返回的接口数据转换为了普通对象,但是当你把这个普通对象push到响应式数组kpi_kalite中时,Vue的响应式系统会自动将新加入的对象包装为Proxy实例,所以打印时看到的是代理对象而非原始普通对象。
场景是否存在问题
正常业务使用下完全没有问题。Proxy代理对象的属性读写、遍历操作和普通对象完全一致,你直接用this.kpi_kalite[0].id、this.kpi_kalite.map(item => item.name)这类常规写法就能正常获取值,不需要做额外转换,也不影响响应式能力。
只有当你需要做深拷贝不希望触发响应式监听、序列化传参、第三方库要求传入原始普通对象等特殊场景时,才需要提取原始值。
解决方法
如果确实需要获取普通对象/数组,可根据场景选择以下方案:
- 方案1:使用Vue官方提供的
toRaw方法提取原始值(推荐)
该方法是Vue原生提供的API,性能损耗极低,不会破坏响应式能力:// 先从vue包引入toRaw import { toRaw } from 'vue' // 需要用原始值的地方调用 const rawKpiList = toRaw(this.kpi_kalite) console.log(rawKpiList) // 输出你预期的普通对象数组 - 方案2:如果该数组不需要响应式,直接定义为普通变量
如果你不需要这个数组的修改触发视图更新,定义变量时不要用ref/reactive声明,直接用普通变量存储即可:// 不要写const kpi_kalite = ref([]) 或者 reactive([]) let kpi_kalite = [] // 后续push的都是普通对象,打印不会出现Proxy - 方案3:临时调试用序列化转换
仅适合临时调试查看值,不要用在业务逻辑中,性能较差:console.log(JSON.parse(JSON.stringify(this.kpi_kalite)))
额外注意:你是在父组件渲染阶段发起异步请求,子组件mounted执行时请求可能还没返回,如果你后续出现Cannot read properties of undefined的报错,可以在父组件调用子组件时加v-if="kpi_kalite.length > 0",等请求返回数据后再渲染子组件即可。
内容的提问来源于stack exchange,提问作者sssss_sssss

