5.3 页面过渡与导航控制


5.3 页面过渡与导航控制

守卫放行后,换页的体感由本节负责:过渡动画怎么配、NuxtLink 的预取何时触发、编程式导航 API 怎么选、滚动位置怎么管理。这些细节单个都不难,合起来决定第二棒的"顺滑度"——第 8 章的性能优化会站在本节肩膀上继续压榨首屏。

页面过渡的最小配置

Nuxt 内置了 Vue 的 transition 挂点,三步开启:

// nuxt.config.ts:开启页面过渡 export default defineNuxtConfig({ app: { pageTransition: { name: 'page', mode: 'out-in' }, }, })
/* assets/css/main.css:过渡的两个状态 */ .page-enter-active, .page-leave-active { transition: opacity 0.18s ease; } .page-enter-from, .page-leave-to { opacity: 0; }

配置生效后,客户端导航时页面组件的离场进场自动套用动画。mode: 'out-in' 表示旧页先走新页再进,避免两页同屏堆叠。按页覆盖用 definePageMeta:

<!-- pages/checkout.vue:结账页换个方向感 --> <script setup> definePageMeta({ pageTransition: { name: 'slide' }, }) </script>

布局也能有独立过渡(layoutTransition),页面换布局时动画外框而不是整个页面。两条实践建议:动画时长控制在两百毫秒级,长动画让应用显得迟钝;离场动画会推迟新页渲染(out-in 模式),性能敏感列表页可按页关闭过渡。

站内跳转一律用 NuxtLink 而不是原生 a 标签——区别不在点击之后(两者都会导航),而在点击之前

<template> <!-- 视口内的 NuxtLink 默认预取目标页的代码与数据 --> <NuxtLink to="/products/42">机械键盘 Pro</NuxtLink> <!-- 关闭预取:低频或超重页面 --> <NuxtLink to="/admin/reports" :prefetch="false">季度报表</NuxtLink> <!-- 外链才用 a 标签 --> <a href="https://example.com" target="_blank" rel="noopener">外部资源</a> </template>

预取机制:NuxtLink 进入视口时,浏览器空闲时段提前拉取目标路由的分片。用户点击时资源已在本地,换页接近瞬时——这是第二棒跑得快的最大功臣,也是它常被忽略的原因(默认开启,没人感知)。代价是流量:列表页几十个链接全部预取会浪费带宽,长列表用 :prefetch="false" 或滚动容器外的链接显式关闭。

编程式导航:navigateTo 与 useRouter

脚本里跳页的标准答案是 navigateTo,它两端可用(服务端中间件里返回它做重定向,5.2 已示范):

<script setup> const router = useRouter() async function deleteOrder(id: number) { await $fetch(`/api/orders/${id}`, { method: 'DELETE' }) // 方式一:navigateTo——推荐,两端可用,支持对象式地址 await navigateTo({ path: '/orders', query: { deleted: id } }) // 方式二:router.push——仅客户端,Vue Router 原生 API // router.push('/orders') } function goBack() { router.back() // 历史栈操作还是 router 直管 } </script>

选择规则:组件与中间件里的跳转用 navigateTo(涵盖 SSR 首航场景);历史栈操作(back/forward)、路由监听用 useRouter。直接用 router.push 的问题在服务端——SSR 管线里它不可用,navigateTo 会自动按环境切换行为。

滚动行为与导航守卫的收尾

两个小而常用的定制。滚动行为——换页后回到顶部还是保留位置:

// app/config 或插件里定制(Nuxt 3.11+ 支持路由选项) export default defineNuxtConfig({ router: { options: { scrollBehaviorType: 'smooth', }, }, })

深层锚点与"返回列表保留滚动位置"的需求,用 useAsyncData 的缓存(同 key 命中不重取)配合 keepalive 或自管 scrollTop 实现,核心思想:数据靠缓存续命,位置靠自己记录

导航中的加载指示——全局进度条开关:

export default defineNuxtConfig({ loadingIndicator: { name: 'circle', color: '#5a7a9a', }, })

慢网环境下顶部细条能显著降低"点了没反应"的焦虑;内网系统追求纯净可以关掉,用页面骨架屏替代(4.3 的三态设计)。

⚠️ 常见坑:out-in 过渡叠加懒加载页面。新页分片还没下载完,离场动画先播完,屏幕停在空白等待。解法是要么让高频路径预取(默认已开),要么过渡模式改 default 并接受两页短暂同屏。

💡 关键直觉:第二棒的快是"提前量"堆出来的——预取把下载藏在浏览之前,过渡把等待藏在动画里,缓存把数据藏在导航之前。三者共同点:把成本挪到用户感知不到的时间段。

本节要点回顾

  • 过渡三步:配置 pageTransition、写两组 CSS 类、按页可用 definePageMeta 覆盖;时长两百毫秒级;
  • NuxtLink 预取:视口内默认预取分片与数据,点击近瞬时;长列表显式关闭防流量浪费;
  • navigateTo 优先:两端通用,服务端重定向与客户端跳页同一 API;历史栈才用 useRouter;
  • 滚动与指示:换页回顶默认行为可定制,全局加载条可开关,慢网建议保留;
  • 预取是隐形加速器:默认开启所以无感知,排查换页卡顿时先确认它没被全局关掉。

作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U