问题
在vue3中利用axios请求回来的数组列表渲染时,在页面刷新后列表丢失
测试
//setup语法塘
let tag = reactive([]);
onBeforeMount(() => {
axios.get(`/api/tags')
.then((res) => {
tag=res;
})
.catch((e) => {
console.log(e);
})
})//获取数据
onMounted(()=>{
console.log(tag);
}
//log:undefined
let tag = ref([]);
onBeforeMount(() => {
axios.get(`/api/tags')
.then((res) => {
tag.value=res;
})
.catch((e) => {
console.log(e);
})
})//获取数据
onMounted(()=>{
console.log(tag);
}
//log:正确响应
let tag = reactive([]);
onBeforeMount(() => {
axios.get(`/api/tags')
.then((res) => {
res.foreach((item,index)=>{
tag[index]=item
})
})
.catch((e) => {
console.log(e);
})
})//获取数据
onMounted(()=>{
console.log(tag);
}
//log:正确响应
发现问题
发现我用ref来代理数组就不会有上述的问题。查了半天也没搞懂。 最后问了问bingai
Proxy 对象可以代理数组,但是不能直接代理数组的索引和长度属性。这是因为数组的索引和长度属性是不可配置的,而 Proxy 对象的拦截器无法修改目标对象的不可配置属性。
如果你想使用 Proxy 对象来实现数组的响应式,你需要使用 ref () 来创建一个包含数组的对象,并通过 .value 属性来访问和修改数组的值。这样,Proxy 对象就可以拦截 .value 属性的操作,从而实现对数组的自定义处理。
已收到消息. Proxy 对象可以代理数组,但是不能直接代理数组的索引和长度属性。这是因为数组的索引和长度属性是不可配置的,而 Proxy 对象的拦截器无法修改目标对象的不可配置属性。 如果你想使用 Proxy 对象来实现数组的响应式,你需要使用 ref () 来创建一个包含数组的对象,并通过 .value 属性来访问和修改数组的值。这样,Proxy 对象就可以拦截 .value 属性的操作,从而实现对数组的自定义处理。
因为我这是跟着尚硅谷的网课上了一遍(他笔记上写的是reactive可以代理数组),还没有了解源码,对proxy也不太熟悉。所以我又问到为什么之前用reactive代理数组,也可以实现响应式。
你可能是在 Vue 3 的 setup () 函数中使用了 reactive () 来代理数组,这样的话,Vue 3 会自动将数组转换为 ref () 类型,从而实现响应式。
但是,如果你在 setup () 函数外部使用 reactive () 来代理数组,那么就会出现问题,因为 reactive () 不能直接代理数组的索引和长度属性。
所以,建议你在使用 reactive () 时,只用于对象,而不是原始类型。如果你想创建一个响应式数组,你应该使用 ref () ,并通过 .value 属性来访问和修改数组的值。
原来如此。。。
总结
以后数组代理最好用ref。
reactive也可以代理但是会在
直接替换数组时失去响应性。
解决方法:
1.使用ref代理数组
单层proxy检测不到数组索引和长度属性得变化,在外面在再包一层ref来监视
2.使用数组得push方法(原理还不清楚)
tag.push(...res);
3.在外面再包一层对像
tag=reactive({list:[]});
tag.list=res;