优化翻页逻辑

This commit is contained in:
2026-05-09 10:25:31 +08:00
parent e9a29d6006
commit 5c1b6a86ca
+74 -1
View File
@@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, watch } from 'vue'; import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
import type { ExtendedPreset, PresetType } from '../../types'; import type { ExtendedPreset, PresetType } from '../../types';
import IconPresetType from '../icons/IconPresetType.vue'; import IconPresetType from '../icons/IconPresetType.vue';
import IconArrowLeft from '../icons/IconArrowLeft.vue'; import IconArrowLeft from '../icons/IconArrowLeft.vue';
@@ -122,6 +122,41 @@ function cleanupDragState() {
dropSide.value = null; dropSide.value = null;
} }
function isTypingTarget(target: EventTarget | null): boolean {
if (!(target instanceof HTMLElement)) return false;
const tag = target.tagName;
return (
tag === 'INPUT' ||
tag === 'TEXTAREA' ||
tag === 'SELECT' ||
target.isContentEditable
);
}
function handleKeydown(event: KeyboardEvent) {
if (totalPages.value <= 1) return;
if (isTypingTarget(event.target)) return;
if (event.key === 'PageDown') {
event.preventDefault();
changePage(currentPage.value + 1);
return;
}
if (event.key === 'PageUp') {
event.preventDefault();
changePage(currentPage.value - 1);
}
}
onMounted(() => {
window.addEventListener('keydown', handleKeydown);
});
onUnmounted(() => {
window.removeEventListener('keydown', handleKeydown);
});
function getTypeLabel(type: PresetType) { function getTypeLabel(type: PresetType) {
const labels: Record<string, string> = { const labels: Record<string, string> = {
positive: '正面', positive: '正面',
@@ -148,6 +183,31 @@ function formatDate(dateStr: string) {
</div> </div>
<template v-else> <template v-else>
<div v-if="totalPages > 1" class="pagination-controls pagination-top">
<button
:disabled="currentPage === 1"
@click="changePage(currentPage - 1)"
class="page-btn nav-btn prev-page"
title="上一页 (PageUp)"
>
<IconArrowLeft width="16" height="16" />
</button>
<div class="page-numbers">
<span class="page-info"> {{ currentPage }} / {{ totalPages }} </span>
<span class="total-count">PageUp / PageDown</span>
</div>
<button
:disabled="currentPage === totalPages"
@click="changePage(currentPage + 1)"
class="page-btn nav-btn next-page"
title="下一页 (PageDown)"
>
<IconArrowRight width="16" height="16" />
</button>
</div>
<div class="preset-grid"> <div class="preset-grid">
<div v-for="preset in displayedPresets" :key="preset.id" class="preset-card nav-btn" draggable="true" <div v-for="preset in displayedPresets" :key="preset.id" class="preset-card nav-btn" draggable="true"
:class="{ :class="{
@@ -239,6 +299,7 @@ function formatDate(dateStr: string) {
:disabled="currentPage === 1" :disabled="currentPage === 1"
@click="changePage(currentPage - 1)" @click="changePage(currentPage - 1)"
class="page-btn nav-btn prev-page" class="page-btn nav-btn prev-page"
title="上一页 (PageUp)"
> >
<IconArrowLeft width="16" height="16" /> <IconArrowLeft width="16" height="16" />
</button> </button>
@@ -252,6 +313,7 @@ function formatDate(dateStr: string) {
:disabled="currentPage === totalPages" :disabled="currentPage === totalPages"
@click="changePage(currentPage + 1)" @click="changePage(currentPage + 1)"
class="page-btn nav-btn next-page" class="page-btn nav-btn next-page"
title="下一页 (PageDown)"
> >
<IconArrowRight width="16" height="16" /> <IconArrowRight width="16" height="16" />
</button> </button>
@@ -543,6 +605,17 @@ function formatDate(dateStr: string) {
margin-top: auto; margin-top: auto;
} }
.pagination-top {
position: sticky;
top: -1rem;
z-index: 5;
margin: -1rem -1rem 1rem;
padding: 0.75rem 1rem;
background: color-mix(in srgb, var(--color-bg-primary) 88%, transparent);
backdrop-filter: blur(10px);
border-bottom: 1px solid var(--color-border);
}
.page-btn { .page-btn {
display: flex; display: flex;
align-items: center; align-items: center;