Vue 3路由页面过渡:实现点击导航下滑露出预加载页面
Vue 3 + Vue Router 页面滑出过渡实现方案
核心问题拆解
你需要实现的是:带固定导航的蓝色页面整体下移滑出,露出底层已就位的红色页面,同时避免复杂的DOM操作和路由钩子逻辑。
组件结构拆分方案
直接按以下层级组织,彻底解决导航栏不跟随移动的问题:
- 根容器:作为视口底座,设置
position: relative; overflow: hidden; height: 100vh; width: 100%;,限制所有子元素在视口内 - 红色特殊视图:固定在根容器底层,根据路由显示/隐藏,设置
position: absolute; top: 0; left: 0; width: 100%; height: 100%; - 可滑动容器:包裹导航栏和蓝色页面内容,设置
position: absolute; top: 0; left: 0; width: 100%; height: 100%; transition: transform 0.6s ease;,通过CSS transform实现滑出 - 导航栏:放在滑动容器内部,用
position: sticky; top: 0;替代fixed,确保跟随滑动容器一起移动
单个<router-view>实现方案
完全可以用单个<router-view>,配合Vue的<Transition>组件和路由元信息实现,无需额外router-view:
App.vue 核心代码
<template> <div class="app-root"> <!-- 红色特殊视图:仅在访问特殊路由时显示 --> <div class="special-red-view" v-if="$route.meta.isSpecial"></div> <!-- 滑动容器:用Transition包裹,路由切换时触发过渡 --> <Transition name="slide-down"> <div class="slide-container" :key="$route.fullPath"> <!-- 导航栏:sticky固定在滑动容器顶部 --> <nav class="yellow-navbar"> <router-link to="/">首页</router-link> <router-link to="/special">特殊页面</router-link> </nav> <!-- 蓝色页面内容区域:承载路由视图 --> <div class="blue-page-content"> <router-view /> </div> </div> </Transition> </div> </template> <style scoped> .app-root { position: relative; overflow: hidden; height: 100vh; width: 100%; } .special-red-view { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: #ff4444; } .slide-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; transition: transform 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55); background-color: #4285f4; } /* 过渡动画:离开时整体下移100vh */ .slide-down-leave-active { transform: translateY(100vh); } .yellow-navbar { position: sticky; top: 0; background-color: #fbbc05; padding: 1rem; z-index: 10; } .blue-page-content { padding: 1rem; height: calc(100vh - 60px); /* 减去导航栏高度,实现内部滚动 */ overflow-y: auto; } </style>
路由配置(router/index.js)
import { createRouter, createWebHistory } from 'vue-router' import Home from '../views/Home.vue' import Special from '../views/Special.vue' const routes = [ { path: '/', name: 'Home', component: Home }, { path: '/special', name: 'Special', component: Special, // 标记为特殊路由,控制红色视图显示 meta: { isSpecial: true } } ] const router = createRouter({ history: createWebHistory(), routes }) export default router
你的疑问解答
- 组件结构拆分:按「根容器 → 红色视图 + 滑动容器(导航栏 + 路由内容)」的层级组织,滑动容器作为可移动的整体,导航栏嵌套其中用sticky固定,彻底解决跟随问题。
- 单个
<router-view>可行性:完全可行,通过<Transition>包裹滑动容器,用$route.fullPath作为key触发路由切换时的过渡,无需额外router-view。 - 避免繁琐JS代码:全程用CSS过渡+Vue内置Transition组件实现,仅通过路由meta字段控制视图显示,不需要在
beforeRouteLeave中操作DOM或样式,逻辑极简。
内容的提问来源于stack exchange,提问作者AnnaGino
相关产品推荐
相关产品推荐

