UniApp 路由导航守

UniApp 路由导航守

大家平时做 Vue 项目,路由守卫基本都是标配:beforeEach 一写,白名单、token 校验、跳转拦截一气呵成。

但换到 UniApp 就会发现一个问题:没有 Vue-Router,也没有 beforeEach。

很多人刚上手都会懵:路由守卫到底怎么写?

其实 UniApp 有自己的方案,就是官方提供的 拦截器(interceptor),今天就把完整可落地、直接复制粘贴的路由守卫给你们。


Vue 里是这样写的

javascript 复制代码
router.beforeEach((to, from, next) => {
  if (to.path === '/login') return next()
  const token = sessionStorage.getItem('token')
  if (!token) return next('/login')
  next()
})

逻辑很简单:

  • 白名单直接过
  • 没 token 跳登录
  • 有 token 正常跳转

但 UniApp 不这套,它的页面跳转全靠:

  • uni.navigateTo
  • uni.redirectTo
  • uni.reLaunch
  • uni.switchTab

所以思路也很直接:把这几个 API 全部拦截,自己做校验。


UniApp 路由守卫核心:拦截器

官方文档里其实写得很清楚:
uni.addInterceptor 可以拦截几乎所有 uni 开头的 API,包括路由、请求、扫码、支付等等。

路由守卫,本质就是:
拦截路由跳转 → 判断权限 → 放行 / 拦截跳登录

拦截器最重要的就是一个方法:
invoke(args)

  • return true = 放行
  • return false = 拦截,不执行原来的跳转

懂这个,整个路由守卫就通了。


直接上代码:utils/interceptor.js

javascript 复制代码
// 全局路由拦截器(路由守卫)
// 在 App.vue onLaunch 中调用一次即可

// 白名单:不需要登录就能访问的页面
const whiteList = new Set([
  '/pages/login/login',
  // '/pages/register/register', 想加就加
])

// 核心校验逻辑
function checkAuth(url) {
  // 截取纯路径,忽略 ? 参数
  const path = url.split('?')[0]

  // 白名单直接放行
  if (whiteList.has(path)) {
    return true
  }

  // 校验 token
  const token = uni.getStorageSync('token')
  return !!token
}

// 拦截器配置
const routeInterceptor = {
  invoke(args) {
    console.log('即将跳转:', args.url)

    // 校验通过,正常跳转
    if (checkAuth(args.url)) {
      return true
    }

    // 未登录 → 跳登录,并把原来要跳的地址带上
    uni.redirectTo({
      url: `/pages/login/login?redirect=${encodeURIComponent(args.url)}`
    })

    // 拦截本次路由跳转
    return false
  }
}

// 注册所有路由拦截
export function initRouteGuard() {
  uni.addInterceptor('navigateTo', routeInterceptor)
  uni.addInterceptor('redirectTo', routeInterceptor)
  uni.addInterceptor('reLaunch', routeInterceptor)
  uni.addInterceptor('switchTab', routeInterceptor)

}

在 App.vue 中启用(非常关键)

为什么必须写在 onLaunch?

因为:
拦截器必须在任何页面跳转之前就注册好

onLaunch 是应用启动最早的生命周期,只执行一次,最适合干这事。

vue 复制代码
<script>
import { initRouteGuard } from '@/utils/interceptor.js'

export default {
  onLaunch() {
    // 启动路由守卫
    initRouteGuard()
  },
  onShow() {},
  onHide() {}
}
</script>

登录成功后如何"回跳原来页面"

拦截时我们拼了一个 redirect 参数:

复制代码
/login?redirect=xxx

登录成功后这样跳回去就行:

javascript 复制代码
async function login() {
  // 登录请求...
  const token = res.data.token
  uni.setStorageSync('token', token)

  // 获取当前页面实例
  const pages = getCurrentPages()
  const current = pages[pages.length - 1]
  const redirect = current.options.redirect

  if (redirect) {
    // 跳回原来想访问的页面
    uni.redirectTo({
      url: decodeURIComponent(redirect)
    })
  } else {
    // 默认跳首页或 tabBar
    uni.switchTab({
      url: '/pages/home/home'
    })
  }
}

一些实用小细节

  1. tabBar 页面也能拦截

    switchTab 已经包含在拦截里,没 token 照样跳登录。

  2. 路径一定要写完整
    /pages/login/login 别写错,不然白名单不生效。

  3. navigateBack 一般不用拦截

    返回上一页通常不需要权限,除非你有特殊场景。

  4. 可扩展权限控制

    想加角色、验过期、验状态,直接在 checkAuth 里加逻辑就行,非常灵活。


总结

  • UniApp 没有 beforeEach,但能用 uni.addInterceptor 实现一模一样的效果
  • 拦截 navigateTo / redirectTo / reLaunch / switchTab 四个 API 就够覆盖所有路由
  • 白名单 + token 校验 = 最常用路由守卫
  • 必须在 App.vue onLaunch 里初始化,否则不生效
  • 代码直接复制,改改页面路径就能上线

这套写法我在好几个 UniApp 项目里都在用,H5、小程序、App 全端稳定,没坑。

相关推荐
miss8 小时前
AI 改完不敢上线?OpenSpec 规约驱动开发实战
前端·代码规范·前端工程化
AiMan8 小时前
腾讯ima还是不可以导出左侧所有对话,只能单条导出,方法不对吗
前端
去伪存真8 小时前
并发量一高就装死?Agent 全链路“防猝死”手册
前端·agent
Moment8 小时前
AI 编程时代,聊聊我的 Mac mini 双屏桌面
前端·后端
AiMan8 小时前
先确认能不能一次把Microsofat Copilot所有内容打包一个文件导出
前端
总要学点什么9 小时前
第97篇:三维数据加载-城市建筑白模自定义着色器——让一条光带沿高度扫上去,快慢却由帧率说了算
前端·gis·webgl·cesium·着色器·空间分析·白模
上海懒图科技9 小时前
工厂厂区电子地图定位导航:厂区人车精准定位,安全合规双保障
前端·arcgis·vue
西安小哥9 小时前
端侧跑大模型,真正的门槛不在参数量:一次 596 秒到 10 秒的压缩路径复盘
前端·人工智能
陈随易10 小时前
Cloudflare 出钱,Vite 团队挑人,44 个维护者分 30 万美元
前端·后端·程序员
恋猫de小郭10 小时前
Flutter THLC 的 WebView 滚动终于从 70 FPS 提升到 120 FPS
android·前端·flutter