任务五 工单2
效果图
1、用户在“取餐”界面中选择查看历史订单时,开发人员已在take-foods.vue文件中实现了登录状态的检查,并据此进行跳转至“历史订单”界面orders.vue(该页面已预先存在)。页面的样式配置通过pages.json文件进行设置,具体配置细节如下:
{
"path": "pages/orders/orders",
"style": {
"navigationBarTitleText": "历史订单",
"navigationBarTextStyle": "black",
"navigationBarBackgroundColor": "#ffffff",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
}
其中,enablePullDownRefresh属性设置为true,意味着将启用监听用户的下拉动作,以启动下拉刷新功能。用户执行下拉操作时,将在onPullDownRefresh()方法中执行相应的下拉刷新处理。而onReachBottomDistance属性值为50,表示当页面滚动至距离底部50像素的位置时,将触发页面上拉触底事件,并在onReachBottom()方法中执行上滑加载数据的操作。
通过API中的orders.js文件获取历史订单数据,定义了一个异步函数getOrders()以获取数据。在Vue框架中,使用async关键字可以声明一个异步函数,该函数内部可以使用await关键字等待异步操作的完成。具体方法如下:
async getOrders(isRefresh = false) {
uni.showLoading({
title: '加载中'
})
setTimeout(() => {
// 这里是1秒后需要执行的代码
this.$api('orders').then((result) => {
if(isRefresh) {//下拉刷新,进行重置数据
this.orders = []
this.page = 1
// 当刷新操作完成后,停止下拉刷新效果
uni.stopPullDownRefresh();
}
// 处理分页数据,重点
result = result.slice(this.pageSize * (this.page - 1), this.pageSize * this.page)
if(result.length) {
this.orders = this.orders.concat(result) //拼接数据
this.page += 1 //上滑一下,页数+1
}else{
uni.showToast({
title: '没有订单了',
icon: 'none'
});
}
uni.hideLoading()
})
}, 500);
在getOrders()方法中,参数用于判断是执行下拉刷新操作还是上滑加载更多数据。通过setTimeout()函数模拟网络延迟以获取数据的效果,具体效果可参见图5.2.2。为了深入学习具体用法,请扫描相应的二维码。在setTimeout()的回调函数内,通过this.$api('orders').then()方法调用数据,最终返回的订单数据封装于result对象中。
鉴于本页面采用分页技术加载数据,分页查询过程中,page与pageSize参数扮演着至关重要的角色,它们共同决定了分页查询的具体行为。page参数指明了当前进行查询的页码,其计数通常以1为起始。例如,page参数值为1时,意味着检索的是第一页的数据;若其值为2,则表示检索的是第二页的数据,依此类推。pageSize参数则定义了每一页所展示的记录数量。例如,当pageSize参数设定为5时,每页将展示5条记录。此参数可根据实际需求进行适当调整,旨在提升用户体验及数据处理的效率。
通过执行result.slice(this.pageSize * (this.page - 1), this.pageSize * this.page)方法,对数据进行切片操作以获取分页数据,并将其赋值给orders对象。若result数组的长度大于零,则表示历史订单中尚有数据存在;若长度为零,则意味着所有数据已加载完毕。此时,应使用uni.showToast方法向用户发出通知,告知其订单数据已全部展示。
orders数组对象包含订单列表数据,其具体对应参数详见列表效果图5.2.3。
其中,orderGoodsName(item.goods)代表一种计算方式,用于将多种商品的名称和数量进行合并拼接。具体实现方法的代码如下:
computed: {
orderGoodsName() {//订单饮品名称
return (goods) => {
let arr = []
goods.forEach(good => arr.push(good.name + '*' + good.number))
return arr.join(',')
}
}
}
遵循前述指导,优化布局结构后,页面在加载、下拉刷新以及上滑加载时调用getOrders()方法以获取数据,从而实现“历史订单”界面的展示效果。具体实现代码如下:
async onLoad() {//页面加载生命周期函数
await this.getOrders(false)
},
async onPullDownRefresh() {//下拉刷新,获取数据
await this.getOrders(true)
},
async onReachBottom() {//上滑加载获取数据,page.json中设置距离
await this.getOrders(false)
}
orders.vue完整代码:
<template>
<!-- 历史记录 -->
<view class="container">
<view class="orders-list d-flex flex-column w-100" style="padding: 20rpx; padding-bottom: 0;">
<view class="order-item" v-for="(item, index) in orders" :key="index" style="margin-bottom: 30rpx;" @tap="detail(item.id)">
<list-cell :hover="false">
<view class="w-100 d-flex align-items-center">
<view class="flex-fill d-flex flex-column">
<view class="font-size-lg text-color-base" style="margin-bottom: 20rpx;">
{{ item.store.name }}
</view>
<view class="font-size-sm text-color-assist">订单编号:{{ item.order_no }}</view>
</view>
<view class="font-size-lg text-color-primary">
{{ item.status_text }}
</view>
</view>
</list-cell>
<list-cell :hover="false" last>
<view class="w-100 d-flex flex-column">
<view class="w-100 text-truncate font-size-lg text-color-base" style="margin-bottom: 20rpx;">
{{ orderGoodsName(item.goods) }}
</view>
<view class="d-flex justify-content-between align-items-center" style="margin-bottom: 30rpx;">
<view class="font-size-sm text-color-assist">
{{ $util.formatDateTime(item.created_at) }}
</view>
<view class="d-flex font-size-sm text-color-base align-items-center">
<view style="margin-right: 10rpx;">共{{ item.goods_num }}件商品,实付</view>
<view class="font-size-lg">¥{{ item.amount }}</view>
</view>
</view>
<view class="d-flex align-items-center justify-content-end">
<view style="margin-right: 10rpx;">
<button type="primary" plain size="mini" v-if="item.invoice_status > 0">查看发票</button>
<button type="primary" plain size="mini" v-else @tap.stop="goToInvoice">开发票</button>
</view>
<view>
<button type="primary" plain size="mini" @tap.stop="review(item)">去评价</button>
</view>
</view>
</view>
</list-cell>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
page:1,//当前分页页数
pageSize:5,//分页数据大小
orders: []
};
},
computed: {
orderGoodsName() {//订单饮品名称
return (goods) => {
let arr = []
goods.forEach(good => arr.push(good.name + '*' + good.number))
return arr.join(',')
}
}
},
async onLoad() {
await this.getOrders(false)
},
async onPullDownRefresh() {//下拉
await this.getOrders(true)
},
async onReachBottom() {//上滑,page.json中设置距离
await this.getOrders(false)
},
methods: {
async getOrders(isRefresh = false) {
uni.showLoading({
title: '加载中'
})
setTimeout(() => {
// 这里是1秒后需要执行的代码
this.$api('orders').then((result) => {
if(isRefresh) {//下拉刷新,进行重置数据
this.orders = []
this.page = 1
// 当刷新操作完成后,停止下拉刷新效果
uni.stopPullDownRefresh();
}
// 处理分页数据,重点
result = result.slice(this.pageSize * (this.page - 1), this.pageSize * this.page)
if(result.length) {
this.orders = this.orders.concat(result)
this.page += 1
}else{
uni.showToast({
title: '没有订单了',
icon: 'none'
});
}
uni.hideLoading()
})
}, 500);
},
}
}
</script>
<style lang="scss" scoped>
</style>