|
1 | 1 | <template> |
2 | 2 | <div class="common-list"> |
3 | 3 | <ul v-if="data.length > 0"> |
4 | | - <template v-for="(item, index) in data" :key="index"> |
5 | | - <li |
6 | | - @click.stop="clickHandle(item, index)" |
7 | | - :class="current === item[props.valueKey] ? 'active color-primary-1' : ''" |
8 | | - class="cursor" |
9 | | - @mouseenter.stop="mouseenter(item)" |
10 | | - @mouseleave.stop="mouseleave()" |
11 | | - > |
12 | | - <slot :row="item" :index="index"> </slot> |
13 | | - </li> |
14 | | - </template> |
| 4 | + <InfiniteScroll |
| 5 | + :size="renderList.length" |
| 6 | + :total="data.length" |
| 7 | + :page_size="paginationConfig.page_size" |
| 8 | + v-model:current_page="paginationConfig.current_page" |
| 9 | + > |
| 10 | + <template v-for="(item, index) in renderList" :key="item[props.valueKey] ?? index"> |
| 11 | + <li |
| 12 | + @click.stop="clickHandle(item, index)" |
| 13 | + :class="current === item[props.valueKey] ? 'active color-primary-1' : ''" |
| 14 | + class="cursor" |
| 15 | + @mouseenter.stop="mouseenter(item)" |
| 16 | + @mouseleave.stop="mouseleave()" |
| 17 | + > |
| 18 | + <slot :row="item" :index="index"> </slot> |
| 19 | + </li> |
| 20 | + </template> |
| 21 | + </InfiniteScroll> |
15 | 22 | </ul> |
16 | 23 | <slot name="empty" v-else> |
17 | 24 | <el-empty :description="$t('common.noData')" /> |
18 | 25 | </slot> |
19 | 26 | </div> |
20 | 27 | </template> |
21 | 28 | <script setup lang="ts"> |
22 | | -import { ref, watch } from 'vue' |
| 29 | +import { ref, watch, reactive, computed } from 'vue' |
23 | 30 |
|
24 | 31 | defineOptions({ name: 'CommonList' }) |
25 | 32 |
|
@@ -48,6 +55,25 @@ watch( |
48 | 55 |
|
49 | 56 | const emit = defineEmits(['click', 'mouseenter', 'mouseleave']) |
50 | 57 |
|
| 58 | +const paginationConfig = reactive({ |
| 59 | + current_page: 1, |
| 60 | + page_size: 50, |
| 61 | + total: 0, |
| 62 | +}) |
| 63 | +
|
| 64 | +// 前端分页滚动加载:data 为全量数据,仅渲染前 current_page * page_size 条,滚动到底再追加 |
| 65 | +const renderList = computed(() => |
| 66 | + props.data.slice(0, paginationConfig.current_page * paginationConfig.page_size), |
| 67 | +) |
| 68 | +
|
| 69 | +// 数据源变化时重置到第一页,避免切换数据后仍停留在很大的页码 |
| 70 | +watch( |
| 71 | + () => props.data, |
| 72 | + () => { |
| 73 | + paginationConfig.current_page = 1 |
| 74 | + }, |
| 75 | +) |
| 76 | +
|
51 | 77 | function mouseenter(row: any) { |
52 | 78 | emit('mouseenter', row) |
53 | 79 | } |
|
0 commit comments