index.vue
3.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
<!--
* @Date: 2025-11-18 16:17:40
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-11-20 17:55:05
* @FilePath: /data-table/src/components/PaginationField/index.vue
* @Description: 分页组件
-->
<template>
<div class="pagination-field">
<div class="indicator">第{{ current + 1 }}页 / 共{{ total }}页</div>
<div class="actions">
<van-button
v-if="showPrev"
:disabled="prev_disabled_effective || current === 0"
round
type="primary"
class="btn"
@click="onPrev"
>{{ prev_label_effective }}</van-button>
<van-button v-if="showNext" round type="primary" class="btn" @click="onNext">{{ nextLabel }}</van-button>
<van-button v-if="showSubmit" round type="primary" class="btn" @click="onSubmit">{{ submitButton.text }}</van-button>
</div>
</div>
<div class="placeholder" />
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
current: { type: Number, default: 0 },
total: { type: Number, default: 1 },
isLast: { type: Boolean, default: false },
prevLabel: { type: String, default: '上一页' },
nextLabel: { type: String, default: '下一页' },
submitButton: { type: Object, default: { text: '提交', back_title: '上一页', is_back: false } },
prevDisabled: { type: Boolean, default: false },
})
const emit = defineEmits(['prev', 'next', 'submit'])
/**
* @description 是否显示上一页按钮(最后一页且 is_back 为 false 时不显示)
* @returns {import('vue').ComputedRef<boolean>}
*/
const showPrev = computed(() => {
// 非最后一页按原逻辑显示;最后一页由 submitButton.is_back 控制显示与否
if (!showSubmit.value) return props.current > 0
return props.current > 0 && props.submitButton?.is_back !== false
})
const showNext = computed(() => props.current < props.total - 1)
const showSubmit = computed(() => props.current === props.total - 1)
/**
* @description 计算上一页按钮文案(最后一页用提交按钮配置的返回文案)
* @returns {import('vue').ComputedRef<string>}
*/
const prev_label_effective = computed(() => {
// 最后一页使用 submitButton.back_title,否则使用外部传入的 prevLabel
return showSubmit.value ? (props.submitButton?.back_title || props.prevLabel) : props.prevLabel
})
/**
* @description 计算上一页按钮禁用状态(最后一页用提交按钮配置的 is_back)
* @returns {import('vue').ComputedRef<boolean>}
*/
const prev_disabled_effective = computed(() => {
// 最后一页直接使用 submitButton.is_back 替换 prevDisabled;否则使用外部传入的 prevDisabled
return showSubmit.value ? (!props.submitButton?.is_back ?? props.prevDisabled) : props.prevDisabled
})
const onPrev = () => emit('prev')
const onNext = () => emit('next')
const onSubmit = () => emit('submit')
</script>
<style lang="less" scoped>
.pagination-field {
position: fixed;
left: 0;
right: 0;
bottom: 0;
background: #fff;
padding: 0.75rem 1rem;
border-top: 1px solid #eaeaea;
display: flex;
flex-direction: column;
align-items: center;
z-index: 10;
.indicator {
font-size: 0.85rem;
color: #666;
margin-bottom: 0.5rem;
}
.actions {
display: flex;
gap: 0.75rem;
.btn {
min-width: 6rem;
}
}
}
.placeholder {
height: 3.75rem;
}
</style>