在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
微信小程序开发之setData?为什么不能频繁 setData 在数据传输时,逻辑层会执行一次 JSON.stringify 来去除掉 setData 数据中不可传输的部分,之后将数据发送给视图层。同时,逻辑层还会将 setData 所设置的数据字段与 data 合并,使开发者可以用 this.data 读取到变更后的数据。 因此频繁调用,视图会一直更新,阻塞用户交互,引发性能问题。 let newState = null const asyncSetData = ({ vm, newData, }) => { newState = { ...newState, ...newData, } Promise.resolve().then(() => { if (!newState) return vm.setData({ ...newState, }) newState = null }) } 由于异步代码会在同步代码之后执行,因此,当你多次使用 asyncSetData 设置 newState 时,newState 都会被缓存起来,并异步 setData 一次 单次设置的数据不能超过 1024kB,请尽量避免一次设置过多的数据 通常,我们拉取到分页的数据 newList,添加到数组里,一般是这么写: this.setData({ list: this.data.list.concat(newList) })
随着分页次数的增加,list 会逐渐增大,当超过 1024 kb 时,程序会报 exceed max data size 错误。 let length = this.data.list.length; let newData = newList.reduce((acc, v, i)=>{ acc[`list[${length+i}]`] = v; return acc; }, {}); this.setData(newData); 这看着似乎还有点繁琐,为了简化操作,我们可以把 list 的数据结构从一维数组改为二维数组:list = [newList, newList], 每次分页,可以直接将整个 newList 赋值到 list 作为一个子数组,此时赋值方式为: let length = this.data.list.length; this.setData({ [`list[${length}]`]: newList }); 同时,模板也需要相应改成二重循环: <block wx:for="{{list}}" wx:for-item="{{listItem}}" wx:key="{{listItem}}"> <child wx:for="{{listItem}}" wx:key="{{item}}"></child> </block> 下拉加载,让我们一夜回到解放前 this.setData({ 'list[-1]': newList }) //哦不,对不起,上面是错的,应该是下面这样: this.setData({ list: this.data.list.unshift(newList) }); 这下好,又是一次性修改整个数组,一夜回到解放前...... 为下拉加载维护一个单独的二维数组 pullDownList let length = this.data.pullDownList.length; this.setData({ [`pullDownList[${length}]`]: newList }); 关键在于渲染时候的反向渲染: <wxs module="utils"> function reverseArr(arr) { console.log return arr.reverse() } module.exports = { reverseArr: reverseArr } </wxs> <block wx:for="{{utils.reverseArr(pullDownList)}}" wx:for-item="{{listItem}}" wx:key="{{listItem}}"> <child wx:for="{{listItem}}" wx:key="{{item}}"></child> </block> <block wx:for="{{list}}" wx:for-item="{{listItem}}" wx:key="{{listItem}}"> <child wx:for="{{listItem}}" wx:key="{{item}}"></child> </block> 问题解决!以上就是本文的全部内容 |
请发表评论