微信小程序瀑布流和虚拟列表

这篇具有很好参考价值的文章主要介绍了微信小程序瀑布流和虚拟列表。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

微信小程序瀑布流和虚拟列表

首先声明虽然本篇是写的微信小程序的案例,但是也可用于H5,思路是想通的,只是有些api的差异,最后会贴代码片段
微信小程序虚拟列表,微信小程序文章来源地址https://www.toymoban.com/news/detail-620230.html

虚拟列表

  • 一般在做长列表优化时,特别是面试时,虚拟列表就是个高频词。这个名词听起来很高级,其实原理很简单
  • 虚拟列表就是将需要渲染的数组数据改造成二维数组,然后通过监听DOM在合适的地方切换为占位元素,达到长列表无限滚动时减少DOM的优化
  • JS
/**
 * 处理占位元素,就是在获取新的数据后
 * 通过SelectQuery获取当前数据的实际高度,然后把这个高度设置到占位元素上
 */
getCurrentItemHeight() {
  const query = this.createSelectorQuery();
  const { virtualId } = this.data
  query.select(`#${virtualId}`).boundingClientRect()
  query.exec((res) => {
    this.setData({
      height: res[0].height
    }, this.observePage())
  })
}

/**
 * 监听元素与页面的相交
 * 可以选择指定元素为参照区域,也可以选择页面为参照元素,只是API不同
 * @doc https://developers.weixin.qq.com/miniprogram/dev/api/wxml/IntersectionObserver.html
 */
observePage() {
  const { virtualId, observeDistance, wrapId } = this.data
  let IntersectionObserver = wx.createIntersectionObserver(this);
  (wrapId ? IntersectionObserver.relativeTo(`#${wrapId}`) : IntersectionObserver.relativeToViewport({ top: observeDistance, bottom: observeDistance }))
  .observe(`#${virtualId}`, ({ intersectionRatio }) => {
    this.setData({
      isShow: intersectionRatio > 0,
    })
  })
}
  • html
<view id="{{virtualId}}">
  <block wx:if="{{isShow}}">
    <slot></slot>
  </block>
  <view wx:else style="height: {{ height }}px"></view>
</view>

瀑布流

  • 瀑布流,又称瀑布流式布局。视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部
  • 瀑布流有多种写法,有通过纯CSS完成的,也有借助JS完成的,方法很多,但是我为了接下来能与虚拟列表相结合,就采用JS的写法,就是通过列数把每一列分为一个单独的子元素,然后会记录每一列的高度,通过判断哪一列高度最小,然后将数据push到高度最小的那一列
/**
 * 获取列表数据
 * @describe 瀑布流处理,哪列高度小,就往哪列push新数据
 */
getList() {
  let { listQuery: { pageIndex, pageSize }, columns, columnsHeight } = this.data;
  for (let i = 0; i < pageSize; i++) {
    const height = Math.floor(Math.random() * 100)
    const item = height < 50 ? height + 50 : height
    const position = this.computePosition(columnsHeight)
    columns[position].push(item)
    columnsHeight += item
  }
  // 在html中双重遍历columns,然后通过flex:1均匀分布
  this.setData({
    columns,
  })
  this.data.columnsHeight = columnsHeight
}

/**
 * 获取高度最小列下标
 */
computePosition(heights) {
  const min = Math.min(...heights);
  return heights.findIndex((item) => item === min)
}

瀑布流结合虚拟列表

  • 让瀑布流有虚拟滚动的能力,思路很简单,就是计算每列的偏移量,因为瀑布流被我们分成了二维数组,所以每块子元素之间就会因为列高度的不一致产生空白区域,所以需要计算这个空白区域的大小,然后通过margin-top移动列元素达到视觉上的瀑布流衔接效果
    微信小程序虚拟列表,微信小程序
getList() {
  let { listQuery: { pageIndex }, column, columnsHeights } = this.data;
  const columns = [];
  // 上一组的高度数据,用于计算偏移值
  const lastHeights = [...columnsHeights];
  // 获取数据
  const list = this.getListData();
  // 初始化当前屏数据
  for (let i = 0; i < column; i++ ) {
    columns.push([]);
  }
  // 遍历新数据,分配至各列
  for (let i = 0; i < list.length; i++) {
    const position = this.computePosition(columnsHeights);
    columns[position].push(list[i]);
    columnsHeights[position] += Number(list[i].height);
  }
  this.setData({
    [`listData[${pageIndex}]`]: {
      columns,
      columnOffset: this.computeOffset(lastHeights),
    }
  });
  this.data.listQuery.pageIndex = pageIndex + 1;
  this.data.columnsHeights = columnsHeights;
},

/**
 * 获取列表数据
 */
getListData() {
  const result = []
  for (let i = 0; i < this.data.listQuery.pageSize; i++) {
    const height = Math.floor(Math.random() * 300);
    const item = {
      height: height < 150 ? height + 150 : height,
      color: this.randomRgbColor(),
    };
    result.push(item);
  }
  return result;
},

/**
 * 随机生成RGB颜色
 */
randomRgbColor() {
  var r = Math.floor(Math.random() * 256); //随机生成256以内r值
  var g = Math.floor(Math.random() * 256); //随机生成256以内g值
  var b = Math.floor(Math.random() * 256); //随机生成256以内b值
  return `rgb(${r},${g},${b})`; //返回rgb(r,g,b)格式颜色
},

/**
 * 获取最小高度列下标
 */
computePosition(heights) {
  const min = Math.min(...heights);
  return heights.findIndex((item) => item === min);
},

/**
 * 计算偏移量
 */
computeOffset(heights) {
  const max = Math.max(...heights);
  return heights.map((item) => max - item);
},

onScrollLower() {
  this.getList();
}
  • WXML
<view>
  <scroll-view class="virtualScrollView" eventhandle scroll-y bindscrolltolower="onScrollLower">
    <block wx:for="{{ listData }}" wx:key="screenIndex" wx:for-index="screenIndex" wx:for-item="screenItem">
      <VirtualItem virtualId="virtual_{{pageIndex}}">
        <view class="fall">
          <block wx:for="{{ screenItem.columns }}" wx:key="columnIndex" wx:for-index="columnIndex" wx:for-item="column" >
            <view style="margin-top: -{{screenItem.columnOffset[columnIndex]}}px;" class="fallCol">
              <view wx:for="{{column}}" style="height: {{ item.height }}px; background-color: {{ item.color }};" wx:key="index" wx:for-item="item" wx:for-index="index">
                screen: {{ screenIndex }}, column: {{ columnIndex }}
              </view>
            </view>
          </block>
        </view>
      </VirtualItem>
    </block>
  </scroll-view>
</view>

总结

  • 代码片段:https://developers.weixin.qq.com/s/5P3DpGmI7PBc

到了这里,关于微信小程序瀑布流和虚拟列表的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 微信小程序 - - - - - 瀑布流效果实现

    对于一些小程序,关于瀑布流的需求是很正常的,瀑布流看起来确实很舒服,但是具体该如何实现呢? 下文给出的方式是: js + css 瀑布流,又称 瀑布流式布局 。 是比较流行的一种网站页面布局, 视觉表现为 参差不齐的多栏布局 ,随着页面滚动条向下滚动,这种布局还会

    2024年02月17日
    浏览(45)
  • 微信小程序的无限瀑布流写法

    微信小程序的无限瀑布流实现总算做完了,换了好几种方法,过程中出现了各种BUG。 首先官方有瀑布流的插件(Skyline /grid-view),不是原生的我就不想引入,因为我的方块流页面已经搭好了,引入说不定就要涉及样式的修改、代码量的增大等麻烦问题。 H5我虽然也做了瀑布流

    2024年02月07日
    浏览(43)
  • 微信小程序实现吸顶、网格、瀑布流布局

    微信小程序开发通常是在webview模式下编写,但是对小程序的渲染性能有一定的追求,就需要使用Skyline模式进行渲染,同时在这种模式下有也有一些特殊的组件,可以轻松的实现想要的效果,本文将介绍在Skyline模式下如何实现吸顶、网格、瀑布流布局。 以下是具体的实现:

    2024年02月22日
    浏览(61)
  • 微信小程序css实现瀑布流布局

    废话不多说 直接上代码 博客地址:BULINGBULING

    2024年02月13日
    浏览(44)
  • 微信小程序实现瀑布流布局(方式一)

    根据奇数列和偶数列区分左边和右边数据 设置width固定,mode=“widthFix” 适用于:左右两列的高度相差不是很大

    2024年02月12日
    浏览(39)
  • uniapp 瀑布流 (APP+H5+微信小程序)

    WaterfallsFlow.vue waterfall.vue

    2024年02月15日
    浏览(63)
  • 微信小程序--列表展示

    小知识: wx:for=\\\"{{list}}\\\"用来循环数组。 wx:for-item=‘变量名(随便起)’   它是指定循环数据当前的变量名,可以通过  {{变量名.属性}} 展示数组的元素。 wx:for-index=‘变量名(随便起)’,它是指向当前元素的下标名,可以在其他事件中定义自定义事件(data-xxx=\\\'{{变量名}}

    2024年02月15日
    浏览(38)
  • 微信小程序——商品列表

    主页面 引入组件 组件部分代码

    2024年02月12日
    浏览(42)
  • 微信小程序 如何实现列表

    微信小程序中实现列表可以通过使用「scroll-view」组件或「list」组件来实现。 使用「scroll-view」组件:可以使用 wx:for 指令来循环渲染列表中的数据,并为每个元素设置相应的样式。 使用「list」组件:该组件已经内置了列表的常用功能,包括列表渲染、上拉加载、下拉刷新等

    2024年02月11日
    浏览(44)
  • 微信小程序 《新闻列表》 案例

    今天带着练习一个小程序的基础练习 《新闻列表》 内容如图: 如要求: 1.主页头部的轮播图 2.中间内容上的信息案列排版。 3.上拉加载内容。 4.在信息加载完成后,给用户提示 我们看一下这个关于轮播图的相关文档。 文档地址:https://developers.weixin.qq.com/miniprogram/dev/compon

    2024年02月08日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包