vue_zhongyou 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +1 -0
- package/package.json +9 -0
- package//344/273/243/347/240/201/assets/common.css +10 -0
- package//344/273/243/347/240/201/components/FilterSortPanel.vue +183 -0
- package//344/273/243/347/240/201/components/card.vue +17 -0
- package//344/273/243/347/240/201/views/HomePage.vue +199 -0
- package//344/273/243/347/240/201/views/listPage.vue +95 -0
- package//344/273/243/347/240/201/views/officialPage.vue +326 -0
- package//344/273/243/347/240/201/views/searchPage.vue +257 -0
- package//345/212/237/350/203/275/344/273/243/347/240/201//345/211/215/347/253/257/347/233/221/346/216/247/errorLogPage.vue +410 -0
- package//345/212/237/350/203/275/344/273/243/347/240/201//345/211/215/347/253/257/347/233/221/346/216/247/errorMonitor.js +324 -0
- package//345/212/237/350/203/275/344/273/243/347/240/201//345/211/215/347/253/257/347/233/221/346/216/247/main.js +103 -0
- package//345/212/237/350/203/275/344/273/243/347/240/201//345/211/215/347/253/257/347/233/221/346/216/247/request.js +89 -0
- package//345/212/237/350/203/275/344/273/243/347/240/201//345/211/215/347/253/257/347/233/221/346/216/247/testError.vue +501 -0
- package//346/226/207/344/273/266/fitler.vue +455 -0
- package//346/226/207/344/273/266/useFilter.vue +110 -0
- package//346/226/207/344/273/266//345/217/257/351/205/215/347/275/256/347/247/273/345/212/250/345/210/227/350/241/250/346/236/266/345/255/220.vue +243 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="mobile-list" ref="listContainer">
|
|
3
|
+
<!-- 列表内容 -->
|
|
4
|
+
<div class="list-content">
|
|
5
|
+
<slot
|
|
6
|
+
:items="displayItems"
|
|
7
|
+
:loading="loading"
|
|
8
|
+
:finished="finished"
|
|
9
|
+
></slot>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<!-- 加载状态 -->
|
|
13
|
+
<div v-if="loading && !finished" class="loading-indicator">
|
|
14
|
+
<el-spinner size="small" />
|
|
15
|
+
<span class="loading-text">加载中...</span>
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<!-- 无更多数据提示 -->
|
|
19
|
+
<div v-if="finished && displayItems.length > 0" class="no-more-data">
|
|
20
|
+
<span>已无更多数据</span>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<!-- 空状态 -->
|
|
24
|
+
<div v-if="!loading && displayItems.length === 0" class="empty-state">
|
|
25
|
+
<slot name="empty">
|
|
26
|
+
<div class="empty-content">
|
|
27
|
+
<el-icon size="40"><el-icon-document /></el-icon>
|
|
28
|
+
<p>暂无数据</p>
|
|
29
|
+
</div>
|
|
30
|
+
</slot>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
</template>
|
|
34
|
+
|
|
35
|
+
<script setup>
|
|
36
|
+
import { ref, onMounted, onUnmounted, computed, watch } from 'vue'
|
|
37
|
+
// import { ElSpinner, ElIcon } from 'element-plus'
|
|
38
|
+
import { Document as ElIconDocument } from '@element-plus/icons-vue'
|
|
39
|
+
|
|
40
|
+
// 定义 props
|
|
41
|
+
const props = defineProps({
|
|
42
|
+
// 数据列表
|
|
43
|
+
items: {
|
|
44
|
+
type: Array,
|
|
45
|
+
default: () => []
|
|
46
|
+
},
|
|
47
|
+
// 每页数据量
|
|
48
|
+
pageSize: {
|
|
49
|
+
type: Number,
|
|
50
|
+
default: 10
|
|
51
|
+
},
|
|
52
|
+
// 总数据量
|
|
53
|
+
total: {
|
|
54
|
+
type: Number,
|
|
55
|
+
default: 0
|
|
56
|
+
},
|
|
57
|
+
// 是否正在加载
|
|
58
|
+
loading: {
|
|
59
|
+
type: Boolean,
|
|
60
|
+
default: false
|
|
61
|
+
},
|
|
62
|
+
// 是否禁用上拉加载
|
|
63
|
+
disabled: {
|
|
64
|
+
type: Boolean,
|
|
65
|
+
default: false
|
|
66
|
+
},
|
|
67
|
+
// 触发加载更多的距离阈值(px)
|
|
68
|
+
offset: {
|
|
69
|
+
type: Number,
|
|
70
|
+
default: 50
|
|
71
|
+
},
|
|
72
|
+
// 是否立即加载第一页
|
|
73
|
+
immediate: {
|
|
74
|
+
type: Boolean,
|
|
75
|
+
default: true
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
// 定义 emits
|
|
80
|
+
const emit = defineEmits([
|
|
81
|
+
'load-more',
|
|
82
|
+
'update:loading'
|
|
83
|
+
])
|
|
84
|
+
|
|
85
|
+
// 响应式数据
|
|
86
|
+
const listContainer = ref(null)
|
|
87
|
+
const currentPage = ref(1)
|
|
88
|
+
const finished = ref(false)
|
|
89
|
+
|
|
90
|
+
// 计算显示的数据
|
|
91
|
+
const displayItems = computed(() => {
|
|
92
|
+
const start = 0
|
|
93
|
+
const end = currentPage.value * props.pageSize
|
|
94
|
+
return props.items.slice(start, end)
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
// 检查是否已经加载完所有数据
|
|
98
|
+
const checkFinished = () => {
|
|
99
|
+
finished.value = displayItems.value.length >= props.total
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// 处理滚动事件
|
|
103
|
+
const handleScroll = () => {
|
|
104
|
+
if (!listContainer.value || props.loading || props.disabled || finished.value) {
|
|
105
|
+
return
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const container = listContainer.value
|
|
109
|
+
const scrollTop = container.scrollTop
|
|
110
|
+
const scrollHeight = container.scrollHeight
|
|
111
|
+
const clientHeight = container.clientHeight
|
|
112
|
+
|
|
113
|
+
// 当滚动到底部时触发加载更多
|
|
114
|
+
if (scrollTop + clientHeight >= scrollHeight - props.offset) {
|
|
115
|
+
loadMore()
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// 加载更多数据
|
|
120
|
+
const loadMore = () => {
|
|
121
|
+
if (finished.value || props.loading) return
|
|
122
|
+
|
|
123
|
+
currentPage.value++
|
|
124
|
+
checkFinished()
|
|
125
|
+
|
|
126
|
+
// 如果还有更多数据,则触发 load-more 事件
|
|
127
|
+
if (!finished.value) {
|
|
128
|
+
emit('load-more', currentPage.value)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// 重置列表状态
|
|
133
|
+
const reset = (silent = false) => {
|
|
134
|
+
currentPage.value = 1
|
|
135
|
+
finished.value = false
|
|
136
|
+
checkFinished()
|
|
137
|
+
|
|
138
|
+
// 如果不是静默重置,则触发第一页加载
|
|
139
|
+
if (!silent && props.immediate) {
|
|
140
|
+
emit('load-more', 1)
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// 手动触发刷新
|
|
145
|
+
const refresh = () => {
|
|
146
|
+
reset()
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// 监听数据变化
|
|
150
|
+
watch(() => props.items, () => {
|
|
151
|
+
checkFinished()
|
|
152
|
+
}, { deep: true })
|
|
153
|
+
|
|
154
|
+
// 监听总数据量变化
|
|
155
|
+
watch(() => props.total, () => {
|
|
156
|
+
checkFinished()
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
// 添加滚动事件监听
|
|
160
|
+
onMounted(() => {
|
|
161
|
+
if (listContainer.value) {
|
|
162
|
+
listContainer.value.addEventListener('scroll', handleScroll)
|
|
163
|
+
}
|
|
164
|
+
checkFinished()
|
|
165
|
+
|
|
166
|
+
// 如果设置了立即加载且有数据需求,则触发第一页加载
|
|
167
|
+
if (props.immediate && props.total > 0 && props.items.length === 0) {
|
|
168
|
+
emit('load-more', 1)
|
|
169
|
+
}
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
// 移除滚动事件监听
|
|
173
|
+
onUnmounted(() => {
|
|
174
|
+
if (listContainer.value) {
|
|
175
|
+
listContainer.value.removeEventListener('scroll', handleScroll)
|
|
176
|
+
}
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
// 暴露方法给父组件
|
|
180
|
+
defineExpose({
|
|
181
|
+
reset,
|
|
182
|
+
refresh,
|
|
183
|
+
loadMore
|
|
184
|
+
})
|
|
185
|
+
</script>
|
|
186
|
+
|
|
187
|
+
<style scoped>
|
|
188
|
+
.mobile-list {
|
|
189
|
+
width: 100%;
|
|
190
|
+
height: 100%;
|
|
191
|
+
overflow-y: auto;
|
|
192
|
+
-webkit-overflow-scrolling: touch;
|
|
193
|
+
position: relative;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.list-content {
|
|
197
|
+
min-height: 100%;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.loading-indicator {
|
|
201
|
+
display: flex;
|
|
202
|
+
justify-content: center;
|
|
203
|
+
align-items: center;
|
|
204
|
+
padding: 16px;
|
|
205
|
+
color: #606266;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.loading-text {
|
|
209
|
+
margin-left: 8px;
|
|
210
|
+
font-size: 14px;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.no-more-data {
|
|
214
|
+
text-align: center;
|
|
215
|
+
padding: 16px;
|
|
216
|
+
color: #909399;
|
|
217
|
+
font-size: 14px;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.empty-state {
|
|
221
|
+
display: flex;
|
|
222
|
+
justify-content: center;
|
|
223
|
+
align-items: center;
|
|
224
|
+
height: 200px;
|
|
225
|
+
color: #909399;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.empty-content {
|
|
229
|
+
text-align: center;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.empty-content p {
|
|
233
|
+
margin-top: 12px;
|
|
234
|
+
font-size: 14px;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/* 移动端适配 */
|
|
238
|
+
@media (max-width: 768px) {
|
|
239
|
+
.mobile-list {
|
|
240
|
+
height: calc(100vh - 50px); /* 预留一些空间给其他元素 */
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
</style>
|