Files
lgp-wx-plus/mixins/productWaterfall.js
年糕崽崽 516f077568 初始化
缺陷:主题配色需要优化整体的同风格
2026-08-14 23:17:19 +08:00

101 lines
3.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 商品瀑布流通用 mixin
*
* product.vue / search.vue 的瀑布流高度同构:data 字段、左右两列 computed、
* 触底加载更多、下拉刷新这些样板代码两边一模一样。这里抽公共,避免改一处忘改另一处。
*
* 约定(引入本 mixin 的页面必须遵守):
* - 页面自己实现 getProductList():负责调接口、按 this.page 把结果赋值/追加到 this.products、
* 维护 this.noMoreData 与 this.loading / this.loadingMore。
* - getProductList 应返回 Promise(供 refreshProductList 关闭下拉动画)。
* - 页面的 onReachBottom / onPullDownRefresh 不用再写,mixin 已接管。
*
* 故意只抽 data + computed + 两个生命周期,不把 getProductList 收进来,
* 因为两个页面的请求参数不同(product 带 category_id,search 只带 title),硬塞进来反而更乱。
*/
export default {
data() {
return {
// 当前页码,从 1 开始
page: 1,
// 每页条数,与后端约定 10
pageSize: 10,
// 商品列表(扁平数组),computed 会拆成左右两列
products: [],
// 首屏 loading(控制骨架屏显隐)
loading: false,
// 触底加载更多 loading
loadingMore: false,
// 是否没有更多数据
noMoreData: false,
// 后端总页数(部分接口会带 last_page)
totalPages: 1,
}
},
computed: {
// 偶数下标 → 左列
leftProducts() {
return this.products.filter((_, index) => index % 2 === 0)
},
// 奇数下标 → 右列
rightProducts() {
return this.products.filter((_, index) => index % 2 === 1)
},
},
onPullDownRefresh() {
this.refreshProductList()
},
onReachBottom() {
this.loadMoreProducts()
},
methods: {
/**
* 下拉刷新:回到第一页重新拉,结束后关闭下拉动画 + toast
* 依赖页面 getProductList 返回 Promise
*/
refreshProductList() {
this.page = 1
this.products = []
this.noMoreData = false
const p = this.getProductList()
Promise.resolve(p)
.then(() => {
uni.stopPullDownRefresh()
uni.showToast({
title: '刷新成功',
icon: 'success',
duration: 1500,
})
})
.catch(() => {
uni.stopPullDownRefresh()
uni.showToast({
title: '刷新失败',
icon: 'none',
duration: 1500,
})
})
},
/**
* 触底加载更多:加锁 + 页码 +1 后交页面 getProductList 处理
* 失败时回退页码,避免下次再触底跳页
*/
loadMoreProducts() {
if (this.loadingMore || this.noMoreData) return
this.page++
this.loadingMore = true
Promise.resolve(this.getProductList())
.catch(() => {
this.page--
uni.showToast({
title: '加载失败',
icon: 'none',
})
})
.finally(() => {
this.loadingMore = false
})
},
},
}