路由动画
INFO
Nuxt3 利用 Vue<Transition>
组件在页面和布局之间应用过度效果
页面
你可以启用页面过度来为所有页面应用页面动画
使用(通用)
- nuxt.config.ts
js
// nuxt.config.ts
export default defineNuxtConfig({
app: {
pageTransition: { name: "page", mode: "out-in" },
},
});
如果你同时更改布局和页面,这里设置的页面过渡效果不会运行,相反你应该设置布局过度效果
- app.vue
html
<template>
<NuxtPage />
</template>
<style>
.page-enter-active,
.page-leave-active {
transition: all 0.4s;
}
.page-enter-from,
.page-leave-to {
opacity: 0;
filter: blur(1rem);
}
</style>
- pages/index.vue
html
<template>
<div>
<h1>首页</h1>
<NuxtLink to="/about">关于页面</NuxtLink>
</div>
</template>
- pages/about.vue
html
<template>
<div>
<h1>关于页面</h1>
<NuxtLink to="/">首页</NuxtLink>
</div>
</template>
单独
如果要为页面设置不同的页面动画,请在页面的definePageMeta
中设置pageTransition
- pages/about.vue
html
<script setup lang="ts">
definePageMeta({
pageTransition: {
name: "rotate",
},
});
</script>
- app.vue
html
<template>
<NuxtPage />
</template>
<style>
/* ... */
.rotate-enter-active,
.rotate-leave-active {
transition: all 0.4s;
}
.rotate-enter-from,
.rotate-leave-to {
opacity: 0;
transform: rotate3d(1, 1, 1, 15deg);
}
</style>
布局
你可以启动布局动画来为所有的布局
添加动画
使用(通用)
- nuxt.config.ts
js
export default defineNuxtConfig({
app: {
layoutTransition: { name: "layout", mode: "out-in" },
},
});
要开始在页面和布局之间添加动画效果,请在app.vue
中添加 css
- app.vue
html
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
<style>
.layout-enter-active,
.layout-leave-active {
transition: all 0.4s;
}
.layout-enter-from,
.layout-leave-to {
filter: grayscale(1);
}
</style>
单独使用
与pageTransition
类似,你可以使用definePageMeta
将自定义的layoutTransition
应用到页面组件
html
<script setup lang="ts">
definePageMeta({
layout: "orange",
layoutTransition: {
name: "rotate",
},
});
</script>
- app.vue
js
<template>
<NuxtPage />
</template>
<style>
/* ... */
.rotate-enter-active,
.rotate-leave-active {
transition: all 0.4s;
}
.rotate-enter-from,
.rotate-leave-to {
opacity: 0;
transform: rotate3d(1, 1, 1, 15deg);
}
</style>
禁用动画
可以为特定的路由禁用pageTransition
和layoutTransition
:
html
<script setup lang="ts">
definePageMeta({
pageTransition: false,
layoutTransition: false,
});
</script>
或在nuxt.config
中全局禁用:
js
defineNuxtConfig({
app: {
pageTransition: false,
layoutTransition: false,
},
});
自定义动画钩子函数
对于高级用例,你可以使用 JavaScript 钩子为 Nuxt
页面创建高度动态和自定义的过渡效果。
这种方式非常适合使用 GSAP
等 JavaScript
动画库。
html
<script setup lang="ts">
definePageMeta({
pageTransition: {
name: "custom-flip",
mode: "out-in",
onBeforeEnter: (el) => {
console.log("进入之前...");
},
onEnter: (el, done) => {},
onAfterEnter: (el) => {},
},
});
</script>
动态过度
要使用条件逻辑应用动态过渡效果,你可以利用内联 middleware
将不同的过渡名称分配给 to.meta.pageTransition
- pages/[id].vue
html
<script setup lang="ts">
definePageMeta({
pageTransition: {
name: "slide-right",
mode: "out-in",
},
middleware(to, from) {
to.meta.pageTransition.name =
+to.params.id > +from.params.id ? "slide-left" : "slide-right";
},
});
</script>
<template>
<h1>#{{ $route.params.id }}</h1>
</template>
<style>
.slide-left-enter-active,
.slide-left-leave-active,
.slide-right-enter-active,
.slide-right-leave-active {
transition: all 0.2s;
}
.slide-left-enter-from {
opacity: 0;
transform: translate(50px, 0);
}
.slide-left-leave-to {
opacity: 0;
transform: translate(-50px, 0);
}
.slide-right-enter-from {
opacity: 0;
transform: translate(-50px, 0);
}
.slide-right-leave-to {
opacity: 0;
transform: translate(50px, 0);
}
</style>
页面现在在前往下一个 id 时应用 slide-left
过渡效果,在前一个 id 时应用 slide-right
过渡效果: