index.vue
5.49 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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<!--
* @Date: 2025-11-18 16:17:40
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-11-26 20:24:04
* @FilePath: /data-table/src/components/PaginationField/index.vue
* @Description: 分页组件
-->
<template>
<div class="pagination-field">
<div class="indicator">第{{ current + 1 }}页 / 共{{ total }}页</div>
<div class="actions">
<div class="actionsLeft">
<van-button
v-if="showPrev"
:disabled="prev_disabled_effective || current === 0"
round
type="primary"
:color="prev_btn_color_effective"
class="btn"
@click="onPrev"
>
<span :style="{ color: prev_text_color_effective }">{{ prev_label_effective }}</span>
</van-button>
</div>
<div class="actionsCenter">
<van-button v-if="showSubmit" round type="primary" :color="submitButton.btn_color" class="btn" @click="onSubmit">
<span :style="{ color: submitButton.text_color }">{{ submitButton.text }}</span>
</van-button>
</div>
<div class="actionsRight">
<van-button v-if="showNext" round type="primary" :color="nextBtnColor" class="btn" @click="onNext">
<span :style="{ color: nextTextColor }">{{ nextLabel }}</span>
</van-button>
</div>
</div>
</div>
</template>
<script setup>
import { computed } from 'vue'
import { styleColor } from "@/constant.js";
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: '下一页' },
prevBtnColor: { type: String, default: styleColor.baseColor },
nextBtnColor: { type: String, default: styleColor.baseColor },
prevTextColor: { type: String, default: '#fff' },
nextTextColor: { type: String, default: '#fff' },
submitButton: { type: Object, default: { text: '提交', back_title: '上一页', is_back: false, btn_color: styleColor.baseColor, text_color: '#fff', prevBtnColor: styleColor.baseColor, prevTextColor: '#fff' } },
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
})
/**
* @description 计算上一页按钮背景色(最后一页用提交按钮颜色)
* @returns {import('vue').ComputedRef<string>}
*/
const prev_btn_color_effective = computed(() => {
// 最后一页按钮使用提交按钮的背景颜色配置;否则使用外部传入的上一页按钮颜色
return showSubmit.value ? (props.submitButton?.prevBtnColor || props.prevBtnColor) : props.prevBtnColor
})
/**
* @description 计算上一页按钮文字颜色(最后一页用提交按钮文字颜色)
* @returns {import('vue').ComputedRef<string>}
*/
const prev_text_color_effective = computed(() => {
// 最后一页按钮文字使用提交按钮的文字颜色;否则使用上一页按钮文字颜色
return showSubmit.value ? (props.submitButton?.prevTextColor || props.prevTextColor) : props.prevTextColor
})
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: grid;
width: 100%;
grid-template-columns: 1fr auto 1fr;
align-items: start; // 垂直方向顶对齐
min-height: 44px; // 保障容器高度,按钮靠顶部
.actionsLeft {
justify-self: start; // 左对齐到边
}
.actionsCenter {
justify-self: center; // 中间居中
}
.actionsRight {
justify-self: end; // 右对齐到边
}
.btn {
min-width: 6rem;
}
}
}
</style>