更新记录

2.7.1(2026-08-31) 下载此版本

修复

  • H5 端返回死循环("无法正常返回,一直来回闪烁") - 修复 onBeforeBack 在 H5 平台的 popstate 返回守卫导致相邻页面间死循环闪烁的问题(issue #39)
    • 现象:H5 端按 首页 → 二级 → 三级 进入后,在三级页执行返回(router.back() 或浏览器后退)时,页面在二、三级之间高频反复切换、无法正常返回,控制台无 JS 报错
    • 根因:H5 返回守卫原采用「history.go(1) 撤销后退 → 守卫放行后 navigateBack 重新后退」策略;navigateBack 在 H5 上会触发多次 popstate,当这些自身 popstate 因派发时机滞后被误判为"新的外部后退"时,会再次进入「撤销 + 重放」分支,形成死循环
    • 修复方案:router.back() 及守卫放行后的返回在发起 navigateBack 前,置位 H5 返回进行中标记,并在时间窗口内放行本次导航产生的所有 popstate(不再进入「撤销 + 重放」分支);同时记录返回目标路径,命中目标 URL 即视为本次返回完成(确定性结束),时间窗口作为兜底自动复位
    • 守卫语义保持:守卫放行时正常返回上一页、守卫中止时停留当前页,均不再出现死循环
    • 涉及文件:router/back-guard.ts(H5 返回进行中标记 + 目标命中判定)、router/index.ts(back() 前置标记)

2.7.0(2026-08-30) 下载此版本

新增

  • H5 端导航动画(CSS 过渡) - 导航动画能力从 App 端扩展到 H5 平台,通过注入的关键帧 CSS 实现与 App 端 animationType 命名对齐的过渡效果(基于 transform / opacity)
    • push(uni.navigateTo)成功后对目标页播放进入动画(animatePageEnter),经 requestAnimationFrame 延后到下一帧以等待页面完成渲染
    • back(uni.navigateBack)先对当前页播放退出动画(animatePageExit),动画结束后再执行真正的返回,使滑出效果与 App 端一致
    • 支持 slide-in/out-*、fade-in/out、zoom、pop 等方向键帧;动画结束(animationend)后自动清理样式,并带定时兜底避免页面快速切换时残留
    • 动画时长默认 300ms(DEFAULT_ANIMATION_DURATION),可通过 duration 覆盖
  • plugins/animation/h5.ts 模块 - H5 动画样式注入(幂等)与进入/退出动画播放逻辑。npm 发布产物由 tsup 构建、不处理 #ifdef H5 条件编译,故采用运行时 getPlatform().isH5 平台判断

优化

  • 导航动画有效值统一在 router 层计算 - meta.animation 仅在注册 AnimationPlugin 时注入导航选项,未注册时即使配置 meta.animation 也不生效;navigate.ts 不再内部回退读取 meta.animation,与调用时传入 animation 的 PLUGIN_REQUIRED 门控保持一致
  • 动画平台能力统一 - App 端为原生窗口动画(animationType),H5 端 push / back 走 CSS 过渡,小程序端由宿主控制

重构

  • 抽出 navigation/helpers/uni-api.ts、plugins/animation/helpers、plugins/interceptor/helpers/parse.ts 等助手模块,收敛导航 API 的 uni 调用与平台判断逻辑

2.6.0(2026-08-27) 下载此版本

新增

  • 全局返回守卫 onBeforeBack - 新增 router.onBeforeBack() 方法,拦截返回操作(App 物理返回键 / 顶部导航栏返回 / uni.navigateBack,H5 浏览器后退按钮 / 后退手势)
    • 返回 false 阻止返回,true / undefined 放行,支持异步(Promise),不受 uni-app onBackPress 同步返回限制
    • App 端通过全局 mixin 的 onBackPress 接入物理返回键 / 导航栏返回 / navigateBack;守卫放行后手动返回,通过内部标记避免递归
    • H5 端通过浏览器 popstate 事件接入后退,采用「撤销后退 → 执行守卫链 → 守卫放行后重新后退」策略
    • 守卫放行后复用 beforeEach → beforeResolve 守卫链,中止 / 重定向行为与完整导航一致
    • 新增 BackGuard / BackGuardReturn 类型
    • 平台限制:App / H5 可拦截;iOS 侧滑返回需配合 app.setSideSlipGesture 禁用手势;小程序原生返回无法拦截
  • iOS 侧滑返回手势控制(app.setSideSlipGesture) - 新增 RouterOptions.app App 平台专属配置,按当前路由动态设置 iOS 侧滑返回手势(对应 plus.webview.setStyle({ popGesture }))
    • 'none' 禁用侧滑返回,使侧滑返回走守卫链(onBeforeBack 生效)
    • 'close' 开启原生侧滑返回,保留原生手势体验(侧滑绕过守卫)
    • 由全局 mixin 在页面 onShow 时自动调用,仅 iOS 平台生效
    • 新增 AppRouterOptions / SideSlipGesture 类型
  • getPlatform() 平台判断工具 - 统一平台判断入口,基于 uni.getSystemInfoSync() 并带缓存
    • 返回 PlatformInfo:isApp / isH5 / isMp / isIOS / isAndroid / uniPlatform / osName
    • 兼容旧版本:uniPlatform 缺失时回退到 typeof plus / typeof window 推断 App / H5
    • 新增 plus 全局对象与 uni.getSystemInfoSync() 类型声明

优化

  • 平台判断统一 - InterceptorPlugin 的 isWebPlatform() 改用 getPlatform().isH5,消除散落的 typeof window / typeof document 特殊判断
查看更多

平台兼容性

uni-app(3.8.3)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
× √ √ √ √ √ √ √ √
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
√ √ √ √ √ √ √ √ √ √ √ √

其他

多语言 暗黑模式 宽屏模式 蒸汽模式
√ √ √ ×

@meng-xi/uni-router

license npm npm

为 uni-app (Vue 3) 提供类似 vue-router 风格的路由管理系统(uni_modules 版本)。

仅支持 Vue 3 — 基于 Vue 3 Composition API,不支持 Vue 2 项目。

特性

  • vue-router 风格 API - push / replace / relaunch / back,自动根据 meta.isTab 切换 switchTab,重复导航自动拒绝,并发导航自动排队
  • 路由守卫 - beforeEach / beforeResolve / afterEach / beforeEnter / onBeforeRouteLeave / onBeforeBack,guardRoute 冷启动补执行,支持可控重定向与守卫超时保护(guardTimeout)
  • 返回拦截 - App 物理返回键 / 导航栏返回 / navigateBack、H5 浏览器后退 / 后退手势均可被守卫拦截;app.setSideSlipGesture 控制 iOS 侧滑手势
  • 命名路由 & 路由元信息 - 通过 name 导航,meta 携带自定义数据(含 isTab、默认动画)
  • TypeScript 类型提示 - 路由名称和路径自动补全与类型检查
  • 插件架构 - ParamsPlugin / ChannelPlugin / InterceptorPlugin / AnimationPlugin 按需注册;未注册时使用对应功能会抛出 PLUGIN_REQUIRED 明确提示
  • 页面间通信 - usePageChannel() 内置通信管理器;默认 push 使用原生 EventChannel,开启 useUniEventChannel 后所有导航方式均支持
  • 声明式导航 - RouterLink(H5 端渲染原生 <a> 标签)+ TabBar / TabBarItem 组件,easycom 自动注册,支持徽标/小红点/切换前拦截与 SCSS 主题定制
  • 页面参数传递 - params 传递复杂数据不暴露 URL,支持 storage 持久化(persistent),back() 后自动保留
  • 查询参数增强 - queryInt() / queryNumber() / queryBool()
  • 导航动画 - push / replace / back 支持动画参数(App 原生窗口动画,H5 端 push / back 有 CSS 过渡),可通过 meta.animation 设置默认
  • 路由状态自动同步 - 全局 Mixin 自动 syncRoute(),支持严格模式(strict)
  • 错误处理 - RouterError / NavigationFailure / UniApiError,RouterErrorCode 错误码,isNavigationFailure() 精准判断
  • 组合式 API - useRouter() / useRoute() / usePageChannel() / onBeforeRouteLeave() / useLink()

安装

将 mxuni-router-v2 目录复制到项目的 uni_modules 目录下即可,无需 npm 安装。

快速开始

1. 创建路由器

// main.ts
import { createSSRApp } from 'vue'
import { createRouter, ParamsPlugin, ChannelPlugin, InterceptorPlugin, AnimationPlugin } from './uni_modules/mxuni-router-v2/js_sdk/index.js'
import App from './App.vue'

const router = createRouter({
    routes: [
        { path: 'pages/index/index', name: 'home', meta: { title: '首页', isTab: true } },
        { path: 'pages/about/about', name: 'about', meta: { requireAuth: true } }
    ],
    plugins: [ParamsPlugin, ChannelPlugin, InterceptorPlugin, AnimationPlugin],
    interceptUniApi: true // 需要 InterceptorPlugin
})

export function createApp() {
    const app = createSSRApp(App)
    app.use(router) // 自动注册全局 mixin,onShow 时同步 currentRoute
    return { app }
}

2. 路由导航

import { useRouter, useRoute } from './uni_modules/mxuni-router-v2/js_sdk/index.js'

const router = useRouter()
const route = useRoute()

await router.push({ path: '/pages/about/about', query: { id: '1' } })
await router.push({ name: 'about' })
await router.push({ path: '/pages/detail/detail', params: { info: { name: 'Tom' } } })
await router.back()

3. 路由守卫

router.beforeEach((to, from) => {
    if (to.meta.requireAuth && !isLoggedIn()) {
        return { name: 'login' } // 重定向到登录页
    }
    // 不返回值(或 return true)表示放行
})

// 全局返回守卫:false 阻止返回,true / undefined 放行,支持异步(Promise)
router.onBeforeBack((to, from) => {
    if (hasUnsavedChanges) {
        return false // 阻止返回
    }
})

4. 组件

组件通过 easycom 自动注册,直接在模板中使用即可:

<!-- RouterLink:声明式导航 -->
<RouterLink :to="{ name: 'about' }">关于</RouterLink>

<!-- TabBar / TabBarItem:自定义底部导航 -->
<TabBar selected-color="#007aff">
    <TabBarItem to="/pages/index/index" icon-path="/static/home.png" text="首页" />
    <TabBarItem to="/pages/about/about" icon-path="/static/user.png" text="我的" dot />
</TabBar>

文档

📖 https://mengxi-studio.github.io/uni-router/

License

MIT

隐私、权限声明

1. 本插件需要申请的系统权限列表:

无

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

许可协议

MIT协议