# vue-router-stack **Repository Path**: lazycatcloud/vue-router-stack ## Basic Information - **Project Name**: vue-router-stack - **Description**: 一个专注于 Vue 路由管理的开源项目,提供灵活的路由栈处理方案,支持路由缓存、页面过渡动画,能解决返回时滚动进度丢失的问题,并可以处理 iOS 手势返回导致的路由动画重复问题。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-11 - **Last Updated**: 2026-06-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # @lazycatcloud/vue-router-stack 基于 Vue 3 和 vue-router 的页面栈路由库。它保留 vue-router 的路由定义和导航能力,同时提供类似移动端页面栈的 DOM 缓存、转场、页面生命周期和调试面板。 当前版本适合浏览器端应用使用,暂不处理 SSR、手势返回识别、每个 tab 独立历史栈。 ## 安装 ```bash pnpm add @lazycatcloud/vue-router-stack vue vue-router ``` 入口处引入样式: ```ts import "@lazycatcloud/vue-router-stack/style.css"; ``` ## 基础使用 创建 router 时使用 `createStackRouter`,其余路由写法保持 vue-router 风格。 ```ts import { createStackRouter, createWebHistory, RouterView, } from "@lazycatcloud/vue-router-stack"; export const router = createStackRouter({ history: createWebHistory(), transition: "slide", transitionDuration: 240, routes: [ { path: "/", component: HomePage, }, { path: "/album", component: RouterView, children: [ { path: "detail", component: AlbumDetail }, { path: "map", component: AlbumMap }, ], }, ], }); ``` 应用入口和普通 vue-router 一样: ```ts import { createApp } from "vue"; import App from "./App.vue"; import { router } from "./router"; createApp(App).use(router).mount("#app"); ``` 页面出口不要直接使用普通 ``,使用 `RouterOutlet`: ```vue ``` 页面组件根节点使用 `RouterPage`: ```vue ``` ## 导航 API 在组件里使用 `useStackRouter()`: ```ts import { useStackRouter } from "@lazycatcloud/vue-router-stack"; const stackRouter = useStackRouter(); stackRouter.push("/album/detail"); stackRouter.replace("/album/detail"); stackRouter.back(); stackRouter.forward(); stackRouter.popTo("/album/detail"); stackRouter.resetRoot("/"); ``` 单次导航可以控制方向、动画、时长和缓动: ```ts stackRouter.push("/search/result", { transition: "fade", }); stackRouter.push("/timeline", { direction: "none", }); stackRouter.push("/detail", { transition: "sheet", duration: 300, easing: "ease-out", }); ``` `direction: "none"` 和 `direction: "root"` 会强制不播放转场,适合 tab 切换和清栈回首页。 ## 转场动画 内置动画: - `slide` - `fade` - `scale` - `none` 可以通过 `defineStackTransition` 注册自定义动画: ```ts import { createStackRouter, defineStackTransition } from "@lazycatcloud/vue-router-stack"; export const router = createStackRouter({ history: createWebHistory(), transition: "slide", transitions: { sheet: defineStackTransition(({ direction }) => ({ entering: direction === "back" ? [{ transform: "translateY(-8%)" }, { transform: "translateY(0)" }] : [{ transform: "translateY(100%)" }, { transform: "translateY(0)" }], leaving: direction === "back" ? [{ transform: "translateY(0)" }, { transform: "translateY(100%)" }] : [{ transform: "translateY(0)" }, { transform: "translateY(-8%)" }], })), }, routes, }); ``` 返回时会优先使用离开页面进入时记录的动画。例如用 `sheet` 打开详情页,返回时会按 `sheet` 收起。 ## 转场决策 `shouldTransition` 用于业务侧决定本次导航是否播放动画。库只提供上下文,不内置 iOS 或具体设备判断。 ```ts const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) || (navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1); export const router = createStackRouter({ history: createWebHistory(), shouldTransition(ctx) { if (isIOS && ctx.source === "external") return false; return ctx.defaultResult; }, routes, }); ``` `ctx.source` 有两个值: - `stack`:由 `stackRouter.push/back/popTo/resetRoot` 等库 API 触发。 - `external`:由浏览器 history 或系统手势等外部来源触发。 ## 页面生命周期 页面被栈缓存时不会频繁卸载,可以使用页面生命周期处理进入和离开: ```ts import { onPageDidEnter, onPageDidLeave, onPageWillEnter, onPageWillLeave, } from "@lazycatcloud/vue-router-stack"; onPageWillEnter(() => {}); onPageDidEnter(() => {}); onPageWillLeave(() => {}); onPageDidLeave(() => {}); ``` 触发顺序保持为: 1. `onPageWillEnter` 2. `onPageWillLeave` 3. 转场动画 4. `onPageDidLeave` 5. `onPageDidEnter` ## 缓存策略 默认页面会缓存,返回时复用旧实例并保留滚动位置和组件状态。 可以在路由 meta 中关闭某个页面的缓存: ```ts { path: "/search/result", component: SearchResult, meta: { stackCache: false, }, } ``` 也可以使用嵌套写法: ```ts { path: "/search/result", component: SearchResult, meta: { stack: { cache: false, }, }, } ``` 通过 `maxStackSize` 限制最大缓存栈长度: ```ts createStackRouter({ history: createWebHistory(), maxStackSize: 30, routes, }); ``` ## 调试面板 开发时可以挂载 `StackRouterDebugPanel` 查看当前栈、缓存、转场和导航来源: ```vue ``` ## Demo 本仓库内置 PC 和 Mobile 两个 demo: - PC:左侧侧边栏 + 右侧内容区 - Mobile:顶部内容区 + 底部栏切换 ```bash pnpm install pnpm dev ``` ## 验证 ```bash pnpm run type-check pnpm test pnpm run build ```