美文网首页
微信小程序组件: 瀑布流列表

微信小程序组件: 瀑布流列表

作者: 牛会骑自行车 | 来源:发表于2022-11-16 08:58 被阅读0次

思路:

  1. 布局按照纵向分布, 以列为单位;
  2. 元素单个儿分配, 每个元素寻找最短的一列;
  3. 填充;
  4. 组件内容循环, 单个儿item设置为抽象节点.

目前情况我很抱歉😂渲染一屏完全没有问题, 可是在进行到上滑加载时, 第一屏到第二屏会稍微卡顿一下, 规律还没观察出来所以没有解决这个问题....

组件代码

wxml

<scroll-view class="flow-scroll" scroll-y enhanced show-scrollbar="{{false}}"  bindscrolltolower="toBottom">
  <view class="flow-container">
    <!-- 按列循环先 -->
    <view wx:if="{{list.length > 0}}" wx:for="{{cols}}" wx:key="index" wx:for-item="col" class="flow-col" style="margin-right: {{index !== cols.length - 1 ? seam : 0}};">
      <!-- 每列数据: 这里用到了抽象节点 -->
      <item wx:for="{{col}}" wx:key="id" wx:for-index="idx" item="{{item}}"></item>
    </view>
  </view>
</scroll-view>

wxss

.flow-scroll {
  width: 100%;
  height: 100%;
}
.flow-container {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}
.flow-col{
  width: 1rem;
  flex: 1 1 auto;
}
.image {
  width: 100%;
}

js

Component({
  properties: {
    // 必传参: 列表数据
    list: {
      required: true,
      type: Array,
      value: []
    },
    // 列数
    colNum: {
      type: Number,
      value: 2
    },
    // 列中间的缝隙
    seam: {
      type: String,
      value: "16rpx"
    },
  },
  data: {
    cols: [],
  },
  methods: {
    initCols() {
      let {
        colNum
      } = this.data;

      // 获取到页面需要几列时, 对列进行设置
      // 主要内容为: 将每个列设置为数组
      let cols = new Array(colNum);
      for (let i = 0; i < cols.length; i++) {
        cols[i] = [];
      }
      this.setData({
        cols
      })
    },
    async renderPage() {
      for (let item of this.data.list) {
        // 涉及到小程序获取没列的高度需要一定的时间, 一个设置完才能设置接下来的一个, 所以得同步
        let {
          minColIndex,
          currentColIndex
        } = await this.renderItem();
        this.setData({
          [`cols[${minColIndex}][${currentColIndex}]`]: item
        })
      }
    },
    renderItem() {
      return new Promise(resolve => {
        this.witchColumn().then(minColIndex => {
          let currentColIndex = this.data.cols[minColIndex].length;
          resolve({
            minColIndex,
            currentColIndex
          })
        });
      })
    },
    witchColumn() {
      return new Promise((resolve => {
        const query = wx.createSelectorQuery().in(this);
        query.selectAll('.flow-col').boundingClientRect().exec(arr => {
          // colsHeightGroup ⬇️
          const colsHeightArr = arr[0].map(col => col.height);
          let minHeightIndex = colsHeightArr.indexOf(Math.min.apply(Math, colsHeightArr));
          resolve(minHeightIndex);
        });
      }))
    },
    toBottom() {
      this.triggerEvent('getMoreData');
    },
  },
  lifetimes: {
    attached() {
      // 进入组件就先对列进行设置
      this.initCols();
    }
  },
  observers: {
    list(list) {
      if (list.length > 0) {
        // 在数据发生变化并且有真实数据时渲染页面
        this.renderPage();
      }
    }
  }
})

json: 目前微信小程序没法像VUE那样子传递循环出的参数并且设置针对单值的插槽儿, 可用的类似方法暂时只能是设置抽象节点.

{
  "component": true,
  "componentGenerics": {
      "item": true
   }
}

以下是列表每一项

emmm我是这么理解的, 就是一个组件中.....又套了一个组件哈哈哈哈哈哈方便传每一项的值, 弥补了小程序不能创建循环中的插槽. 不过它真正的作用

https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/generics.html

wxml

<view class="flow-item">
  <image src="{{item.url}}" mode="widthFix" class="image"></image>
  <view class="introduce">{{item.content}}</view>
</view>

js

Component({
  properties: {
    // 必传参: 对应每项的参数们
    item: {
      required: true,
      type: Object,
      value: {}
    }
  },
})

tada~回头完善掉开篇的bug我们再来哟

相关文章

网友评论

      本文标题:微信小程序组件: 瀑布流列表

      本文链接:https://www.haomeiwen.com/subject/rfgotdtx.html