322 lines
7.7 KiB
Vue
322 lines
7.7 KiB
Vue
<template>
|
||
<view class="demo-container">
|
||
<view class="demo-header">
|
||
<text class="demo-title">OrderList组件演示</text>
|
||
<text class="demo-subtitle">集成z-paging组件,支持虚拟列表、下拉刷新、上拉加载更多</text>
|
||
</view>
|
||
|
||
<!-- 功能控制区 -->
|
||
<view class="control-section">
|
||
<view class="control-row">
|
||
<button class="control-btn" @click="toggleVirtualList">
|
||
{{ useVirtualList ? '关闭' : '开启' }}虚拟列表
|
||
</button>
|
||
<button class="control-btn" @click="toggleEmptyState">
|
||
{{ showEmpty ? '显示数据' : '显示空状态' }}
|
||
</button>
|
||
</view>
|
||
<view class="control-row">
|
||
<button class="control-btn" @click="addMoreData">
|
||
添加更多数据
|
||
</button>
|
||
<button class="control-btn" @click="clearData">
|
||
清空数据
|
||
</button>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- OrderList组件演示 -->
|
||
<view class="demo-list">
|
||
<OrderList
|
||
:orderList="orderList"
|
||
:hasMore="hasMore"
|
||
:isLoading="isLoading"
|
||
:currentTab="currentTab"
|
||
:emptyText="emptyText"
|
||
:useVirtualList="useVirtualList"
|
||
:virtualListHeight="'500px'"
|
||
:cellHeightMode="cellHeightMode"
|
||
:fixedHeight="120"
|
||
@refresh="handleRefresh"
|
||
@loadMore="handleLoadMore"
|
||
@orderClick="handleOrderClick"
|
||
@orderCall="handleOrderCall"
|
||
@orderComplete="handleOrderComplete"
|
||
/>
|
||
</view>
|
||
|
||
<!-- 功能说明 -->
|
||
<view class="feature-section">
|
||
<text class="feature-title">新功能特性:</text>
|
||
<view class="feature-list">
|
||
<text class="feature-item">✅ 集成z-paging组件</text>
|
||
<text class="feature-item">✅ 支持虚拟列表,提升大数据渲染性能</text>
|
||
<text class="feature-item">✅ 自定义下拉刷新样式和文案</text>
|
||
<text class="feature-item">✅ 自定义上拉加载更多样式和文案</text>
|
||
<text class="feature-item">✅ 自动管理空数据状态</text>
|
||
<text class="feature-item">✅ 支持固定高度和自适应高度模式</text>
|
||
<text class="feature-item">✅ 完整的事件回调机制</text>
|
||
<text class="feature-item">✅ 响应式设计,适配各种屏幕</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, computed } from 'vue'
|
||
import OrderList from './index.vue'
|
||
|
||
// 响应式数据
|
||
const orderList = ref([])
|
||
const hasMore = ref(true)
|
||
const isLoading = ref(false)
|
||
const currentTab = ref('all')
|
||
const useVirtualList = ref(true)
|
||
const cellHeightMode = ref('auto')
|
||
const showEmpty = ref(false)
|
||
|
||
// 计算属性
|
||
const emptyText = computed(() => {
|
||
return showEmpty.value ? '暂无数据,点击刷新重试' : '暂无工单数据'
|
||
})
|
||
|
||
// 模拟数据
|
||
const generateMockData = (count = 10, startId = 1) => {
|
||
const data = []
|
||
for (let i = 0; i < count; i++) {
|
||
data.push({
|
||
id: `${startId + i}`,
|
||
title: `工单标题 ${startId + i} - ${['空调维修', '水管漏水', '电路故障', '网络异常', '设备更换'][i % 5]}`,
|
||
createTime: new Date(Date.now() - Math.random() * 7 * 24 * 60 * 60 * 1000).toLocaleString(),
|
||
contactName: ['张先生', '李女士', '王先生', '赵女士', '刘先生'][i % 5],
|
||
contactPhone: `138****${String(Math.floor(Math.random() * 10000)).padStart(4, '0')}`,
|
||
status: ['pending', 'processing', 'completed'][i % 3],
|
||
type: 'service'
|
||
})
|
||
}
|
||
return data
|
||
}
|
||
|
||
// 初始化数据
|
||
const initData = () => {
|
||
orderList.value = generateMockData(20)
|
||
}
|
||
|
||
// 切换虚拟列表
|
||
const toggleVirtualList = () => {
|
||
useVirtualList.value = !useVirtualList.value
|
||
uni.showToast({
|
||
title: `虚拟列表已${useVirtualList.value ? '开启' : '关闭'}`,
|
||
icon: 'none'
|
||
})
|
||
}
|
||
|
||
// 切换空状态
|
||
const toggleEmptyState = () => {
|
||
showEmpty.value = !showEmpty.value
|
||
if (showEmpty.value) {
|
||
orderList.value = []
|
||
hasMore.value = false
|
||
} else {
|
||
initData()
|
||
hasMore.value = true
|
||
}
|
||
}
|
||
|
||
// 添加更多数据
|
||
const addMoreData = () => {
|
||
const newData = generateMockData(10, orderList.value.length + 1)
|
||
orderList.value.push(...newData)
|
||
uni.showToast({
|
||
title: '已添加10条数据',
|
||
icon: 'success'
|
||
})
|
||
}
|
||
|
||
// 清空数据
|
||
const clearData = () => {
|
||
orderList.value = []
|
||
hasMore.value = false
|
||
uni.showToast({
|
||
title: '数据已清空',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
|
||
// 下拉刷新
|
||
const handleRefresh = async () => {
|
||
console.log('下拉刷新')
|
||
isLoading.value = true
|
||
|
||
// 模拟网络请求
|
||
await new Promise(resolve => setTimeout(resolve, 1500))
|
||
|
||
// 重新加载数据
|
||
orderList.value = generateMockData(15)
|
||
hasMore.value = true
|
||
isLoading.value = false
|
||
|
||
uni.showToast({
|
||
title: '刷新成功',
|
||
icon: 'success'
|
||
})
|
||
}
|
||
|
||
// 上拉加载更多
|
||
const handleLoadMore = async () => {
|
||
console.log('上拉加载更多')
|
||
|
||
if (!hasMore.value) return
|
||
|
||
// 模拟网络请求
|
||
await new Promise(resolve => setTimeout(resolve, 1000))
|
||
|
||
// 添加新数据
|
||
const newData = generateMockData(10, orderList.value.length + 1)
|
||
orderList.value.push(...newData)
|
||
|
||
// 模拟没有更多数据
|
||
if (orderList.value.length >= 50) {
|
||
hasMore.value = false
|
||
}
|
||
|
||
uni.showToast({
|
||
title: `加载了${newData.length}条数据`,
|
||
icon: 'none'
|
||
})
|
||
}
|
||
|
||
// 工单点击
|
||
const handleOrderClick = (orderData) => {
|
||
console.log('点击工单:', orderData)
|
||
uni.showToast({
|
||
title: `点击了工单: ${orderData.title}`,
|
||
icon: 'none'
|
||
})
|
||
}
|
||
|
||
// 工单呼叫
|
||
const handleOrderCall = (orderData) => {
|
||
console.log('呼叫工单:', orderData)
|
||
uni.showToast({
|
||
title: `呼叫: ${orderData.contactName}`,
|
||
icon: 'none'
|
||
})
|
||
}
|
||
|
||
// 工单完成
|
||
const handleOrderComplete = (orderData) => {
|
||
console.log('完成工单:', orderData)
|
||
// 更新状态
|
||
const index = orderList.value.findIndex(item => item.id === orderData.id)
|
||
if (index !== -1) {
|
||
orderList.value[index].status = 'completed'
|
||
}
|
||
uni.showToast({
|
||
title: '工单已标记为完成',
|
||
icon: 'success'
|
||
})
|
||
}
|
||
|
||
// 初始化
|
||
initData()
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.demo-container {
|
||
padding: 20rpx;
|
||
background-color: #f5f5f5;
|
||
min-height: 100vh;
|
||
}
|
||
|
||
.demo-header {
|
||
text-align: center;
|
||
margin-bottom: 40rpx;
|
||
|
||
.demo-title {
|
||
display: block;
|
||
font-size: 36rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
margin-bottom: 10rpx;
|
||
}
|
||
|
||
.demo-subtitle {
|
||
display: block;
|
||
font-size: 26rpx;
|
||
color: #666;
|
||
line-height: 1.5;
|
||
}
|
||
}
|
||
|
||
.control-section {
|
||
background: white;
|
||
border-radius: 16rpx;
|
||
padding: 30rpx;
|
||
margin-bottom: 30rpx;
|
||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
|
||
|
||
.control-row {
|
||
display: flex;
|
||
gap: 20rpx;
|
||
margin-bottom: 20rpx;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
}
|
||
|
||
.control-btn {
|
||
flex: 1;
|
||
padding: 20rpx;
|
||
background: linear-gradient(135deg, #007aff 0%, #0056cc 100%);
|
||
color: white;
|
||
border: none;
|
||
border-radius: 12rpx;
|
||
font-size: 26rpx;
|
||
transition: all 0.3s ease;
|
||
|
||
&:active {
|
||
transform: scale(0.95);
|
||
background: linear-gradient(135deg, #0056cc 0%, #003d99 100%);
|
||
}
|
||
}
|
||
}
|
||
|
||
.demo-list {
|
||
height: 500px;
|
||
background: white;
|
||
border-radius: 16rpx;
|
||
overflow: hidden;
|
||
margin-bottom: 30rpx;
|
||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
|
||
}
|
||
|
||
.feature-section {
|
||
background: white;
|
||
border-radius: 16rpx;
|
||
padding: 30rpx;
|
||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
|
||
|
||
.feature-title {
|
||
display: block;
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
|
||
.feature-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 12rpx;
|
||
}
|
||
|
||
.feature-item {
|
||
font-size: 28rpx;
|
||
color: #666;
|
||
line-height: 1.5;
|
||
padding-left: 10rpx;
|
||
}
|
||
}
|
||
</style> |