背景:
基于vue3开发列表页, 页面使用v-for循环内置指令
解决问题:
列表数据初始化问题
解决方案:
reactive
let tableData = reactive([]) // 用于列表显示
axios.get('xxx').then(res=>{
tableData.length = 0
let list = res.list ?? []
if(list.length){
tableData.push(...list)
}
})
该方案使用reactive()创建响应式,因为有分页和查询需求,所以ajax请求响应后tableData数组先通过length属性进行清空,再通过push添加元素。
问题:代码处理繁琐,性能低下
shallowRef
let tableData = shallowRef<ClusterListRow[]>([]) // 用于列表显示
axios.get('xxx').then(res=>{
let list = res.list ?? []
if(list.length){
tableData.value = list
}
})
该方案通过shallowRef,减少数据结构深层的响应式。也避免了每次都要清空数组和一个一个元素添加到数组的操作。因此性能得到提升
vue3内置指令的响应式
我们要解决的是数据的初始化,能不能先不用响应式呢? 大胆尝试下
let tableData = null // 用于列表显示
axios.get('xxx').then(res=>{
let list = res.list ?? []
if(list.length){
tableData= list
}
})
该方案变量没有初始响应式,ajax请求响应后直接赋值,页面竟然重新渲染了。
和团队成员讨论,可能是因为接口响应很快,页面还没挂在,tableData的值变化后才挂载的。
然后通过setTimeout() 设置的间隔时间很长,结果页面还是能够渲染。
通义千问的结论是setup:
然而,通过猜想,原因可能是内置自定义指令v-for,通过实验得出,确实是v-for的绑定导致的响应式。同时,又测试了v-if内置指令。同样可以在初始化时不设置响应式,ajax请求后赋值页面也会变化。