微信小程序——用Lin UI实现瀑布流和触底加载

总之先上效果图


image.png

瀑布流是使用Lin UI实现的所以要先安装Lin UI

数据请求与处理

原始的api有两个参数

  • start 获取记录的起始序号
  • count 一次获取记录的条数

这是封装后的函数之后会用到

static async getLatestSpu(start, count)

这是请求到的数据格式

{
"total":1,  // 数据总条数
    "count":10, // 每页展示条数
    "page":0,   // 页码
    "total_page":1, // 总页数
    "items":[
        {
            "title":"ins复古翠绿NoteBook",
            "subtitle":"林白默默的掏出小本本,将她说的话一次不漏的记了下来。",
            "img":"",
            "price":"29.99",
            "discount_price":"27.8",
            "description":null,
            "tags":"林白推荐"   // 标签以$分割
        }
    ]
}

瀑布流组件的使用方法

Lin UI中的瀑布流组件使用了小程序中抽象节点l-water-flow-item中传入一个组件作为瀑布流中的单元格,之后通过wx.lin.renderWaterFlow(data, refresh, success)函数进行渲染其中data参数需要一个数组是瀑布流中所需要的数据,refresh参数为是否刷新数据(删除之前已经加载的数据),success渲染成功后的回调函数

编写瀑布流需要的组件

先新建一个组件。
根据需求Lin UI中的card组件tag组件和price组件很适合用来编写需要的瀑布流单元格先把他们在json文件中引入

{
  "component": true,
  "usingComponents": {
    "l-card": "/miniprogram_npm/lin-ui/card/index",
    "l-tag": "/miniprogram_npm/lin-ui/tag/index",
    "l-price": "/miniprogram_npm/lin-ui/price/index"
  }
}

这是组件的js文件

Component({
  properties: {
    data: Object,   // 接收瀑布流数组元素
    showBasePrice: { // 显示原价
      type: Boolean,
      value: false
    }
  },
  data: {
    tags: []  // 标签数组
  },
  lifetimes: {
    attached() {
      const tags = this.properties.data.tags.split('$');  // 将标签分割成数组
      this.setData({tags});
    }
  }
});

有的地方瀑布流不需要显示原价showBasePrice属性可以用来控制是否显示原价
接下来是wxml文件

<l-card type="cover" image="{{data.img}}" title="{{data.title}}" image-mode="widthFix"
        l-class="card-container" l-img-class="card-img" l-title-class="card-title">
    <view class="content-text">
        <view class="tag-container">
            <block wx:for="{{tags}}">
                <l-tag wx:if="{{item}}" bg-color="#DCEBE6" font-color="#557862" l-class="tag-item">{{item}}</l-tag>
            </block>
        </view>
        <view class="price">
<!--            需要显示原价且有优惠价-->
            <block wx:if="{{showDiscount && data.discount_price}}">
                <l-price unit="¥" value="{{data.discount_price}}" unit-color="#557862" value-color="#557862" size="36" bold="600"/>
                <l-price unit="¥" wx:if="{{data.price}}" unit-color="#666" value="{{data.price}}" deleted value-color="#666" del-color="#666"/>
            </block>
<!--            不需要显示原价-->
            <l-price unit="¥" wx:elif="{{data.discount_price}}" value="{{data.discount_price}}" unit-color="#557862" value-color="#557862" size="36" bold="600"/>
            <l-price unit="¥" wx:else value="{{data.price}}" unit-color="#557862" value-color="#557862" size="36" bold="600"/>
        </view>
        <text class="describe">{{data.subtitle}}</text>
    </view>
</l-card>

wxml中用到的组件用法参考
card组件文档
tag组件文档
price组件文档

wxss文件就不贴了

触底加载

小程序中因为有onReachBottom()函数触底加载比较好实现,分页的控制比较麻烦,所以我写了一个PageBean用来控制分页

export class PageBean {
    count;  // 每页条数
    start;  // 开始位置
    total;  // 总数据条数
    isEnd = false;  // 是否是最后一页
    
    // 初始化
    constructor(count = 6) {
        this.start = 0;
        this.count = count;
    }

    // 将pageBean的属性改到下一页
    nextPage() {
        if (!this.total || (this.start + this.count) < this.total) {
            this.start += this.count;
        } else {
            this.isEnd = true;
        }
    }
}

下面是触底翻页的代码

async onReachBottom() {
    // 判断本页不是最后一页且没有在加载
    if (!this.page.isEnd && !this.data.onLoad) {
        // 设置状态正在加载
        this.setData({
            onLoad: true
        });
        const spuList = await Spu.getLatestSpu(this.page.start, this.page.count);
        wx.lin.renderWaterFlow(spuList.items, false, () => {
            this.page.nextPage();
            // 设置状态为加载完毕
            this.setData({
                onLoad: false
            })
        });
    } else if (this.page.isEnd) {
        this.setData({
            isEnd: true
        });
    }
}

page是PageBean的实例化对象,在第一次加载数据时设置page对象的total值,这样可以保证加载到最后一条后不再加载。onLoad是表示是否正在加载isEnd表示是否加载到最后一页

交互反馈

触底加载需要提示用户加载状态这个微信的wx.showToast()可以做到但是感觉太low了,Lin UI有一个Loadmore组件可以做底部提示

RW5CNX.jpg

是这样用的

<view>
    <l-water-flow generic:l-water-flow-item="r-goods-water"/>
    <l-loadmore show="{{onLoad}}" type="loading" loading-text="正在加载" line/>
    <l-loadmore show="{{isEnd}}" type="end" end-text="到底了" line/>
</view>

用到的属性的含义
show:是否显示页底提示
type:页底提示类型
loading-text:加载中状态的文案
end-text:加载完成状态的文案
line:是否显示分割线

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 因新工作主要负责微信小程序这一块,最近的重心就移到这一块,该博客是对微信小程序整体的整理归纳以及标明一些细节点,初...
    majun00阅读 7,445评论 0 9
  • 连接连接 大哥大法官
    禾枫沐雨阅读 456评论 0 0
  • 今天你在意的一切,困住你的枷锁,所有的、明天都将不复存在。 你在意什么,就会为什么所困。
    墨迹未染阅读 275评论 0 0
  • 听着一曲《红豆》安慰着入梦,词那么动容,王菲唱的那么情真,似幻影中点点滴滴的相思梦…… 忍不住拿起手机,敲打起心中...
    上善若水菇凉阅读 302评论 0 0