feat: 添加页面切换动画
This commit is contained in:
+60
@@ -24,3 +24,63 @@ useHead({
|
||||
</NuxtLayout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.slide-left-enter-active,
|
||||
.slide-left-leave-active,
|
||||
.slide-right-enter-active,
|
||||
.slide-right-leave-active {
|
||||
transition:
|
||||
opacity 0.2s ease-in-out,
|
||||
transform 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
/* 前进:新页面从右侧滑入 */
|
||||
.slide-left-enter-from {
|
||||
opacity: 0;
|
||||
transform: translateX(32px);
|
||||
}
|
||||
.slide-left-enter-to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
/* 前进:旧页面向左消失 */
|
||||
.slide-left-leave-from {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
.slide-left-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateX(-32px);
|
||||
}
|
||||
|
||||
/* 后退:新页面从左侧滑入 */
|
||||
.slide-right-enter-from {
|
||||
opacity: 0;
|
||||
transform: translateX(-32px);
|
||||
}
|
||||
.slide-right-enter-to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
/* 后退:旧页面向右消失 */
|
||||
.slide-right-leave-from {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
.slide-right-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateX(32px);
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.slide-left-enter-active,
|
||||
.slide-left-leave-active,
|
||||
.slide-right-enter-active,
|
||||
.slide-right-leave-active {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// app/middleware/page-transition.global.ts - 根据页面 pageOrder 动态切换滑动方向
|
||||
// 离开动画依赖 from.meta,进入动画依赖 to.meta,需要同时设置才能保证方向一致
|
||||
export default defineNuxtRouteMiddleware((to, from) => {
|
||||
const toOrder = Number(to.meta.pageOrder ?? 0);
|
||||
const fromOrder = Number(from.meta.pageOrder ?? 0);
|
||||
|
||||
const name = toOrder >= fromOrder ? "slide-left" : "slide-right";
|
||||
to.meta.pageTransition = { name };
|
||||
from.meta.pageTransition = { name };
|
||||
});
|
||||
@@ -5,7 +5,11 @@ import QaRecordsTable from "@/components/dashboard/QaRecordsTable.vue";
|
||||
import StatsOverview from "@/components/dashboard/StatsOverview.vue";
|
||||
import { useAnswerStore } from "@/stores/answer";
|
||||
|
||||
definePageMeta({ middleware: "auth" });
|
||||
definePageMeta({
|
||||
middleware: "auth",
|
||||
pageOrder: 2,
|
||||
pageTransition: { name: "slide-left" }
|
||||
});
|
||||
|
||||
const answerStore = useAnswerStore();
|
||||
|
||||
|
||||
@@ -4,6 +4,11 @@ import AnswerForm from "@/components/home/AnswerForm.vue";
|
||||
import AnswerResult from "@/components/home/AnswerResult.vue";
|
||||
import OcsConfigCard from "@/components/home/OcsConfigCard.vue";
|
||||
|
||||
definePageMeta({
|
||||
pageOrder: 1,
|
||||
pageTransition: { name: "slide-left" }
|
||||
});
|
||||
|
||||
useHead({
|
||||
title: "OCS AI 答题服务"
|
||||
});
|
||||
|
||||
+11
-2
@@ -15,6 +15,11 @@ import {
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { useAuthStore } from "@/stores/auth";
|
||||
|
||||
definePageMeta({
|
||||
pageOrder: 3,
|
||||
pageTransition: { name: "slide-left" }
|
||||
});
|
||||
|
||||
useHead({ title: "登录 - OCS AI 答题服务" });
|
||||
|
||||
const authStore = useAuthStore();
|
||||
@@ -30,7 +35,9 @@ const formSchema = toTypedSchema(
|
||||
.string({ required_error: "邮箱不能为空" })
|
||||
.min(1, "邮箱不能为空")
|
||||
.email("请输入有效的邮箱地址"),
|
||||
password: z.string({ required_error: "密码不能为空" }).min(1, "密码不能为空")
|
||||
password: z
|
||||
.string({ required_error: "密码不能为空" })
|
||||
.min(1, "密码不能为空")
|
||||
})
|
||||
);
|
||||
|
||||
@@ -91,7 +98,9 @@ const onSubmit = handleSubmit(async (values) => {
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
:disabled="isSubmitting || authStore.loading || !authStore.initialized"
|
||||
:disabled="
|
||||
isSubmitting || authStore.loading || !authStore.initialized
|
||||
"
|
||||
class="w-full"
|
||||
>
|
||||
{{ authStore.loading ? "登录中..." : "登录" }}
|
||||
|
||||
@@ -15,6 +15,11 @@ import {
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { useAuthStore } from "@/stores/auth";
|
||||
|
||||
definePageMeta({
|
||||
pageOrder: 4,
|
||||
pageTransition: { name: "slide-left" }
|
||||
});
|
||||
|
||||
useHead({ title: "注册 - OCS AI 答题服务" });
|
||||
|
||||
const authStore = useAuthStore();
|
||||
@@ -115,7 +120,9 @@ const onSubmit = handleSubmit(async (values) => {
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
:disabled="isSubmitting || authStore.loading || !authStore.initialized"
|
||||
:disabled="
|
||||
isSubmitting || authStore.loading || !authStore.initialized
|
||||
"
|
||||
class="w-full"
|
||||
>
|
||||
{{ authStore.loading ? "注册中..." : "注册" }}
|
||||
|
||||
@@ -6,6 +6,13 @@ export default defineNuxtConfig({
|
||||
compatibilityDate: "2025-07-15",
|
||||
devtools: { enabled: true },
|
||||
|
||||
app: {
|
||||
pageTransition: {
|
||||
name: "slide-left",
|
||||
mode: "out-in"
|
||||
}
|
||||
},
|
||||
|
||||
css: ["~/assets/css/tailwind.css"],
|
||||
|
||||
vite: {
|
||||
|
||||
Reference in New Issue
Block a user