小程序技巧系列

您所在的位置:网站首页 百度小程序web化 小程序技巧系列

小程序技巧系列

2023-10-10 06:00| 来源: 网络整理| 查看: 265

「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战」

前言:在移动端两栏的瀑布流交互方式还是很常见的,大多用在图文的展示上,在这里记录下自己的实现方式,供有需要的人参数

什么是瀑布流布局

视觉表现就是一种参差不齐的多栏布局,随着页面的滚动,随之加载数据。其实本质就是容器内有多个高度不一致的元素展示,既多行等宽元素的一种顺序排列。

布局原理

本片文章只实现移动端比较常见的两栏瀑布流,并且是小程序生产环境可用的,所以就不再赘述一些其他方式的实现。

页面分成左右两个容器,各对应一组数据。 将每一列当做一个容器,在数据侧先将数据分为左右两个数组。每次插入时,计算下左右的高度,依次插入到高度较低的那一个容器。 实际效果

屏幕录制2022-02-20 下午12.53.25.gif

实现

新建waterfall自定义组件

布局 .waterfall-wrap { display: flex; width: 100%; box-sizing: border-box; justify-content: space-between; } .item { width: 100%; border: 1px solid rosybrown; border-radius: 16rpx; margin-bottom: 20rpx; } 渲染逻辑

使用小程序提供的boundingClientRect获取布局节点的位置信息,这样就可以获取到容器的高度,来做插入判断。 具体实现,看代码:

Component({ data: { leftList: [], rightList: [] }, methods: { oneByOneRender(data = [], i, success) { if (data.length > i) { this.getBoundingClientRect((res) => { const rects = res[0]; if (rects && rects.length) { const leftH = rects[0].height; const rightH = rects[1].height; if (leftH { this.oneByOneRender(data, ++i, success); }) } }) } else { success && success(); } }, run(data, success, isLast) { if(this.columnNodes) { this.render(data, success, isLast); } else { this.selectDom(() => { this.render(data, success, isLast); }) } }, getBoundingClientRect(cb){ this.columnNodes.boundingClientRect().exec(cb) }, render(data = [], success, isLast) { if(isLast) { return this.oneByOneRender(data, 0, success) } this.columnNodes.boundingClientRect().exec((res) => { const rects = res[0]; if (rects && rects.length) { let container = ''; if (rects[0].height { this.data[container].push(item); if (container === 'leftList') { container = 'rightList' } else { container = 'leftList' } }) } this.setData({ leftList: this.data.leftList, rightList: this.data.rightList }, () => { }) }) }, selectDom(cb) { const query = this.createSelectorQuery(); this.columnNodes = query.selectAll('#left, #right'); cb && cb(); } }, }); 性能优化

由于小程序的双线程架构,频繁的setData会对性能有较大的损害,因此我们要尽可能的减少setData,因此对于一个瀑布流来说,我们正常滚动过程中,对一次加载的数据,先判断当前左右容器的高度,然后将数据遍历,分成2份,最后直接一次setData。 只有当是最后一页数据时,保证我们瀑布流不会出现一边很高,一边很低。这个时候我们做到每插入一个元素都去计算左右容器的高度,保证正确的插入顺序,样式上做到符合预期。 代码已在上面体现。

调用

调用这里,我们不使用数据传递,而是直接调用自定义组件内的方法,在使用的页面内:

// 模拟接口数据 setTimeout(() => { this.waterfallRef = this.selectComponent('#waterfallFlow'); this.waterfallRef.run(this.data.dataList, () => { }); }, 1000) // 加载更多 onReachBottom() { this.waterfallRef.run(this.data.dataList, () => { }, true); },

这里是使用页面的滚动到底部的钩子函数,同理也可以使用在scroll-view组件内。

总结

本文的重点其实性能优化这点,由于小程序双线程的架构,因此数据-》渲染这块,整体效率较低。为了交互更友好,体验更好。因此我这里想的是,正常的加载过程中,只判断当前容器的高度,然后直接将数据分为两份,然后对应加载。只有当是最后一页时,才没插入一个计算一个,保证最后左右两侧不会出现一边很高,一边很低的现象。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3