Uncaught (in promise) TypeError: 'get' on proxy: property X is a read-on
Author:zhoulujun Date:
今天vue迁移过来的逻辑发生报错。
'get' on proxy: property “**' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value
我们可以使用vue3里面的 toRaw去解决:
文档表示 toRaw 方法从 reactive 对象中获取到的是原始数据
意思就是toRaw 能将响应式对象转换为普通对象。
本质就是用原对象,不要用代理过的
具体的,需要通读:vue3响应性API学习笔记 https://www.zhoulujun.cn/html/webfront/ECMAScript/vue3/8685.html
shallowRef和shallowReactive
ref和reactive都属于递归监听,也就是数据的每一层都是响应式的,如果数据量比较大,非常消耗性能,非递归监听只会监听数据的第一层。
ref定义的数据每一层都是响应式数据
shallowRef定义的数据,只有第一层是响应式的,即只有在更改.value的时候才能实现响应式
const age = ref({ a: 1, b: { c: { d: 1 } } });//每一层都是响应式数据 const age = shallowRef({ a: 1, b: { c: { d: 1 } } }); //只有第一层是响应式的,即只有在更改.value的时候才能实现响应式使用shallowRef后,可以通过triggerRef()方法主动更新界面,实现界面刷新
同理,reactive和shallowReactive(shallowReactive没有类似triggerRef()的方法)
toRaw与markRaw
toRaw的出现是解决什么问题呢?
toRaw可以将由reactive或readonly函数转换成响应式代理的普通对象,对普通对象的属性值进行修改,就不会更新视图界面。一般用于渲染具有不可变数据源的大列表,跳过代理转换可以提高性能。
有些时候我们不希望数据进行响应式实时更新,可以通过toRaw获取ref或reactive引用的原始数据,通过修改原始数据,不会造成界面的更新,只有通过修改ref和reactive包装后的数据时才会发生界面响应式变化。
let obj1 = {...}; //state和obj1是引用关系,state的本质是一个Proxy对象,其中引用了obj1 let state = reactive(obj1); //通过toRaw方法获取到原始数据,其实是获取到obj1的内存地址,obj2和obj1是完全相等的 let obj2 = toRaw(state) console.log(obj1 === obj2);//true在使用reactive定义数据时一般不会先定义一个obj,再将他传给reactive,都是直接在reactive中写数据的。
为了性能优化,vue3提供了更多的选择
转载本站文章《Uncaught (in promise) TypeError: 'get' on proxy: property X is a read-on》,
请注明出处:https://www.zhoulujun.cn/html/webfront/ECMAScript/vue3/8858.html