feat: 新增订单列表交互
This commit is contained in:
265
pages/order/components/OrderList/index.vue
Normal file
265
pages/order/components/OrderList/index.vue
Normal file
@@ -0,0 +1,265 @@
|
||||
<template>
|
||||
<view class="order-list-container">
|
||||
<!-- z-paging组件 -->
|
||||
<z-paging
|
||||
ref="paging"
|
||||
v-model="dataList"
|
||||
:refresher-enabled="true"
|
||||
:refresher-threshold="45"
|
||||
refresher-default-text="下拉刷新"
|
||||
refresher-pulling-text="下拉刷新"
|
||||
refresher-refreshing-text="正在刷新..."
|
||||
refresher-complete-text="刷新完成"
|
||||
:loading-more-enabled="true"
|
||||
loading-more-default-text="点击加载更多"
|
||||
loading-more-loading-text="正在加载..."
|
||||
loading-more-no-more-text="没有更多了"
|
||||
loading-more-fail-text="加载失败,点击重试"
|
||||
:empty-view-text="emptyText"
|
||||
:empty-view-img="emptyIcon"
|
||||
:auto="false"
|
||||
:use-virtual-list="false"
|
||||
:virtual-list-height="virtualListHeight"
|
||||
:cell-height-mode="cellHeightMode"
|
||||
:fixed-height="fixedHeight"
|
||||
:safe-area-inset-top="true"
|
||||
:use-page-scroll="true"
|
||||
:top-offset="120"
|
||||
@query="queryList"
|
||||
@emptyViewReload="handleEmptyReload"
|
||||
>
|
||||
<!-- 非虚拟列表模式下的数据渲染 -->
|
||||
<view class="order-list-content">
|
||||
<OrderCard
|
||||
v-for="(item, index) in currentDataList"
|
||||
:key="item.id || index"
|
||||
:orderData="item"
|
||||
@click="handleOrderClick"
|
||||
@call="handleOrderCall"
|
||||
@complete="handleOrderComplete"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 虚拟列表模式下的数据渲染 -->
|
||||
<template #cell="{ item }" v-if="useVirtualList">
|
||||
<OrderCard
|
||||
:orderData="item"
|
||||
@click="handleOrderClick"
|
||||
@call="handleOrderCall"
|
||||
@complete="handleOrderComplete"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<!-- 自定义空状态 -->
|
||||
<template #empty v-if="customEmptyView">
|
||||
<view class="custom-empty">
|
||||
<image :src="emptyIcon" class="empty-icon" />
|
||||
<text class="empty-text">{{ emptyText }}</text>
|
||||
<button
|
||||
class="refresh-btn"
|
||||
@click="handleEmptyReload"
|
||||
v-if="showRefreshBtn"
|
||||
>
|
||||
刷新重试
|
||||
</button>
|
||||
</view>
|
||||
</template>
|
||||
</z-paging>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, defineProps, watch, onMounted, computed, nextTick } from "vue";
|
||||
import OrderCard from "../OrderCard/index.vue";
|
||||
|
||||
// Props
|
||||
const props = defineProps({
|
||||
// 工单数据列表
|
||||
orderList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
// 是否有更多数据
|
||||
hasMore: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
// 是否正在加载
|
||||
isLoading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 空状态文案
|
||||
emptyText: {
|
||||
type: String,
|
||||
default: "暂无工单数据",
|
||||
},
|
||||
// 空状态图标
|
||||
emptyIcon: {
|
||||
type: String,
|
||||
default: "/static/images/empty.png",
|
||||
},
|
||||
// 是否显示刷新按钮
|
||||
showRefreshBtn: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
// 当前Tab类型
|
||||
currentTab: {
|
||||
type: String,
|
||||
default: "all",
|
||||
},
|
||||
// 是否启用虚拟列表
|
||||
useVirtualList: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
// 虚拟列表高度
|
||||
virtualListHeight: {
|
||||
type: [String, Number],
|
||||
default: "100%",
|
||||
},
|
||||
// 单元格高度模式
|
||||
cellHeightMode: {
|
||||
type: String,
|
||||
default: "auto", // auto | fixed
|
||||
},
|
||||
// 固定高度(当cellHeightMode为fixed时使用)
|
||||
fixedHeight: {
|
||||
type: Number,
|
||||
default: 120,
|
||||
},
|
||||
// 是否使用自定义空状态
|
||||
customEmptyView: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits([
|
||||
"refresh",
|
||||
"loadMore",
|
||||
"orderClick",
|
||||
"orderCall",
|
||||
"orderComplete",
|
||||
]);
|
||||
|
||||
// 响应式数据
|
||||
const paging = ref(null);
|
||||
const dataList = ref([]);
|
||||
const pageNum = ref(1);
|
||||
const pageSize = ref(10);
|
||||
|
||||
// 计算属性
|
||||
const currentDataList = computed(() => {
|
||||
return props.orderList || [];
|
||||
});
|
||||
|
||||
// 查询列表数据
|
||||
const queryList = async (pageNo, pageSize, from) => {
|
||||
console.log("z-paging查询:", { pageNo, pageSize, from });
|
||||
|
||||
try {
|
||||
// 触发父组件的数据加载事件
|
||||
if (pageNo === 1) {
|
||||
// 下拉刷新
|
||||
emit("refresh");
|
||||
} else {
|
||||
// 上拉加载更多
|
||||
emit("loadMore");
|
||||
}
|
||||
|
||||
// 等待数据更新
|
||||
await nextTick();
|
||||
|
||||
// 直接使用当前的orderList数据
|
||||
const currentData = props.orderList || [];
|
||||
|
||||
// 在非虚拟列表模式下,z-paging主要用于下拉刷新和上拉加载
|
||||
// 数据渲染通过模板中的v-for完成
|
||||
paging.value?.complete(currentData, !props.hasMore);
|
||||
|
||||
} catch (error) {
|
||||
console.error("查询列表失败:", error);
|
||||
paging.value?.complete(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 处理空状态重新加载
|
||||
const handleEmptyReload = () => {
|
||||
console.log("空状态重新加载");
|
||||
paging.value?.reload();
|
||||
};
|
||||
|
||||
// 处理工单点击
|
||||
const handleOrderClick = (orderData) => {
|
||||
emit("orderClick", orderData);
|
||||
};
|
||||
|
||||
// 处理工单呼叫
|
||||
const handleOrderCall = (orderData) => {
|
||||
emit("orderCall", orderData);
|
||||
};
|
||||
|
||||
// 处理工单完成
|
||||
const handleOrderComplete = (orderData) => {
|
||||
emit("orderComplete", orderData);
|
||||
};
|
||||
|
||||
// 监听orderList变化,更新z-paging数据
|
||||
watch(
|
||||
() => props.orderList,
|
||||
(newList) => {
|
||||
if (newList && newList.length >= 0) {
|
||||
dataList.value = [...newList];
|
||||
// 在非虚拟列表模式下,主要是通知z-paging数据已更新
|
||||
if (paging.value) {
|
||||
paging.value.complete(newList, !props.hasMore);
|
||||
}
|
||||
}
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
);
|
||||
|
||||
// 监听Tab切换,重新加载数据
|
||||
watch(
|
||||
() => props.currentTab,
|
||||
() => {
|
||||
nextTick(() => {
|
||||
paging.value?.reload();
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// 组件挂载后初始化
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
// 初始化数据
|
||||
if (currentDataList.value.length > 0) {
|
||||
dataList.value = [...currentDataList.value];
|
||||
// 手动触发z-paging的数据更新
|
||||
if (paging.value) {
|
||||
paging.value.complete(currentDataList.value, !props.hasMore);
|
||||
}
|
||||
} else {
|
||||
// 如果没有初始数据,触发第一次查询
|
||||
if (paging.value) {
|
||||
paging.value.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
reload: () => paging.value?.reload(),
|
||||
refresh: () => paging.value?.reload(),
|
||||
complete: (data, noMore) => paging.value?.complete(data, noMore),
|
||||
getPaging: () => paging.value,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "./styles/index.scss";
|
||||
</style>
|
||||
Reference in New Issue
Block a user