总之先上效果图
瀑布流是使用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
组件可以做底部提示
是这样用的
<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:是否显示分割线