小程序瀑布流实现

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

什么是瀑布流布局

瀑布流布局,一般等宽,不等高的列表排列

原理是找出高度之和最小的那一列,在高度最小列继续添加元素

可以通过 absolute 定位实现,动态计算每一项的 topleft

微信小程序瀑布流组件库:me-waterfall,JavaScript,小程序,小程序,javascript,瀑布流

封装瀑布流方法

function getAllRect(context, selector) {
  return new Promise(function (resolve) {
    wx.createSelectorQuery()
      .in(context)
      .selectAll(selector)
      .boundingClientRect()
      .exec(function (rect) {
        if (rect === void 0) {
          rect = []
        }
        return resolve(rect[0])
      })
  })
}

/**
 * 瀑布流
 * @param {*} context 页面或组件this对象
 * @param {string} selector 选择器
 * @param {Object} options
 * @param {number=375} options.width 屏幕宽度
 * @param {number=2} options.column 列数
 * @param {number|string} options.gap 每列直接的间隙
 * @param {number=0} options.padding 整个列表左右的padding
 * @param {number=0}
 * @returns {Array} 计算每项的top、left、height的数组
 */
async function waterFall(context, selector, options = {}) {
  let items = await getAllRect(context, selector)
  if (items.length <= 0) return []
  let { gap = 15, column = 2, padding = 0, width = 375, firstColumnToTop = 0 } = options
  // 1- 确定列数  = 页面的宽度 / 图片的宽度,单例的宽度
  let itemWidth = items[0].width
  // 定义每一列之间的间隙 px
  if (gap === 'auto') {
    gap = (width - itemWidth * column) / (column - 1)
  }
  let _columnHeightArr = [] // 保存每列高度
  let result = []

  for (let i = 0, len = items.length; i < len; i++) {
    if (i < column) {
      // 2- 确定第一行
      let top = firstColumnToTop
      let left = (itemWidth + gap) * i + padding
      // 瀑布流列表左右padding
      if (i === 0 || i === len - 1) {
        left = padding
      }
      _columnHeightArr.push(items[i].height - top)
      result.push({
        top,
        left,
        height: items[i].height,
      })
    } else {
      // 其他行
      // 3- 找到数组中最小高度  和 它的索引
      let minHeight = Math.min(..._columnHeightArr)
      let minIndex = _columnHeightArr.findIndex((item) => item === minHeight)
      // 4- 设置下一行的第一个盒子位置
      // top值就是最小列的高度 + gap
      result.push({
        top: _columnHeightArr[minIndex] + gap,
        left: result[minIndex].left,
        height: items[i].height,
      })

      // 5- 修改最小列的高度
      // 最小列的高度 = 当前自己的高度 + 拼接过来的高度 + 间隙的高度
      _columnHeightArr[minIndex] = _columnHeightArr[minIndex] + items[i].height
    }
  }

  return result
}

使用

vim demo.wxml

    <!--需要子元素撑大父元素高度的情况,才需要设置height-->
    <view class="goods_list flex flex-wrap relative" style="width:100%;height:{{height}}">
        <block wx:for="{{list}}" wx:key="index">
          <view class="goods_item" style="position:absolute;top:{{ item.top }}px;left:{{ item.left }}px"
                bindtap="handleItem" data-item="{{item}}">
            <view class="goods_img">
              <goodsImage detail="{{ {imgUrl:item.goodsIcon} }}" isAllowCash="{{true}}">
              </goodsImage>
            </view>
            <view class="goods_mes">
              <view class="goods_name g-t-over2">{{item.goodsName}}</view>
              <view class="goods_price">{{item.price}}</view>
            </view>
          </view>
        </block>
    </view>

vim demo.js

// 需要在节点加载到页面后调用
onReady() {
  const { screenWidth, list } = this.data
  waterFall(this, '.goods_item', { width: screenWidth, gap: 'auto' }).then((arr) => {
    if (!arr.length) return
    let lastNode = arr[arr.length - 1]
    let height = lastNode.top + lastNode.height + 'px'
    this.setData({
      list: list.map((item, index) => ({ ...item, ...arr[index] })),
      height,
    })
  })
}

效果

微信小程序瀑布流组件库:me-waterfall,JavaScript,小程序,小程序,javascript,瀑布流

小结

既然都封装成函数了,为什么不封装成组件调用呢?

组件调用可以参考这个小程序的瀑布流组件me-waterfall

我看了这个组件的源码,用到组件间关系来实现瀑布流结构,整个瀑布流组件内部也需要父子组件关系,父组件监听子组件插入元素,获取元素的动态高度,往高度最小列添加新元素。

但是我引入使用,在组件内使用me-waterfall 组件,组件间关系方法 linked 不生效,官方论坛也找不到原因,便弃用。
类似这样的结构:

<!--page.wxml-->
<view>
	<goodsList />
</view

<!--goodsList.wxml-->
<view>
	<me-waterfall>
	  <me-waterfall-item wx:for="{{list}}" wx:key="index">
	    <image src="{{item.imgUrl}}" style="width:100%;height:{{item.height}}px" />
	  </me-waterfall-item>
	</me-waterfall>
</view

于是,自己封装一个方法使用。便有了此文。

封装成方法也有优点,不需要引入组件,简单引入一下方法调用即可。文章来源地址https://www.toymoban.com/news/detail-657462.html

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

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

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

相关文章

  • 微信小程序实现瀑布流布局(方式一)

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

    2024年02月12日
    浏览(39)
  • Vue3瀑布流(Waterfall)

    Vue2瀑布流(Waterfall)  瀑布流_百度百科 可自定义设置以下属性: 图片数组(images),类型:Array{title?: string, src: string},默认 [] 要划分的列数(columnCount),类型:number,默认 3 各列之间的间隙(columnGap),类型:number,单位px,默认 30 瀑布流区域的总宽度(width),类型:

    2023年04月22日
    浏览(33)
  • 微信小程序--瀑布流

    本文使用了微信小程序第三方组件库 Lin UI 。 Lin UI 是基于 微信小程序原生语法 实现的组件库。遵循简洁,易用的设计规范。 Lin UI 中封装了瀑布流的组件,使用方法也比较简单,但是写法让我不是很理解,因此决定下载源码研究。 以下将从 如何使用 , 源码研究 , 源码改

    2024年02月09日
    浏览(35)
  • 微信小程序瀑布流布局

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

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

    2024年02月07日
    浏览(41)
  • 微信小程序瀑布流和虚拟列表

    首先声明虽然本篇是写的微信小程序的案例,但是也可用于H5,思路是想通的,只是有些api的差异,最后会贴代码片段 虚拟列表 一般在做长列表优化时,特别是面试时,虚拟列表就是个高频词。这个名词听起来很高级,其实原理很简单 虚拟列表就是将需要渲染的数组数据改

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

    WaterfallsFlow.vue waterfall.vue

    2024年02月15日
    浏览(58)
  • 微信小程序组件 实现加载中效果

    大家好哇,我是梦辛工作室的灵,我又来了=-=,最近项目开发中,需实现一个加载效果,上图给大家看下: 感觉一般把,还是挺好写的,我就封装成了一个组件,方便大家以后使用,使用方法如下: 还是简单吧,原理其实也很简单,就是 n个正方形(中间一根线) 旋转 后就

    2024年02月12日
    浏览(50)
  • 基于微信小程序地图组件实现行车轨迹

    微信小程序是一款能够开发出各种功能的便捷工具,其中内置的地图组件,为我们提供了强大的地图展示和交互的能力,为我们的开发节约了不少时间和精力。同时,利用微信小程序内置的定时器,我们也能够简单地实现经纬度轨迹移动的效果。 在这个程序中,我们需要用到

    2024年02月03日
    浏览(51)
  • 微信小程序实现数值监听(页面和组件属性)

    简介 目前文章主要介绍对页面属性值的监听以及组件属性值的监听。需要异页面监听数据,请跳转至另一个文章介绍 为什么需要监听属性值 当需要通过一个属性变化时候,需要计算相应的方法等。pc网站经常需要监听属性,那么小程序应该怎么去实现? 1、首先创建公共的

    2024年02月09日
    浏览(57)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包