index.vue 2.98 KB
<!--
 * @Date: 2025-11-18 16:17:40
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2025-11-20 17:46: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: true } },
    prevDisabled: { type: Boolean, default: false },
})

const emit = defineEmits(['prev', 'next', 'submit'])

const showPrev = computed(() => props.current > 0)
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>