uniapp路由拦截实现方法

Uniapp 路由拦截实现方法

Uniapp 提供了比微信小程序更灵活的路由拦截方式,可以通过以下几种方法实现:

1. 使用全局前置守卫(推荐)

在 main.js 或 router.js 中配置全局前置守卫:

javascript 复制代码
// main.js
import App from './App'
import { onLaunch } from '@dcloudio/uni-app'

// 路由拦截器
const routerInterceptor = (to, from, next) => {
  // 白名单页面直接放行
  const whiteList = ['/pages/login/login', '/pages/index/index']
  if (whiteList.includes(to.path)) {
    return next()
  }
  
  // 检查登录状态
  const token = uni.getStorageSync('token')
  if (!token) {
    uni.redirectTo({
      url: '/pages/login/login'
    })
    return
  }
  
  next()
}

// 注册全局前置守卫
uni.addInterceptor('navigateTo', {
  invoke(args) {
    routerInterceptor({ path: args.url }, {}, () => {
      args.url = args.url // 正常跳转
    })
  },
  fail(err) {
    console.log('interceptor-fail', err)
  }
})

// 类似添加其他路由方法的拦截
uni.addInterceptor('redirectTo', { /*...*/ })
uni.addInterceptor('switchTab', { /*...*/ })

App.mpType = 'app'
const app = new App({
  //...
})

2. 封装统一路由方法

javascript 复制代码
// utils/router.js
export default {
  navigateTo(options) {
    if (this.checkAuth(options.url)) {
      uni.navigateTo(options)
    } else {
      this.toLogin()
    }
  },
  
  redirectTo(options) {
    // 类似实现
  },
  
  checkAuth(url) {
    const whiteList = ['/pages/login/login']
    if (whiteList.includes(url)) return true
    
    const token = uni.getStorageSync('token')
    return !!token
  },
  
  toLogin() {
    uni.redirectTo({
      url: '/pages/login/login'
    })
  }
}

使用时代替原生方法:

javascript 复制代码
import router from '@/utils/router'
router.navigateTo({
  url: '/pages/user/user'
})

3. 使用页面生命周期拦截

在需要拦截的页面的 onLoad 或 onShow 中检查:

javascript 复制代码
// pages/user/user.vue
export default {
  onShow() {
    const token = uni.getStorageSync('token')
    if (!token) {
      uni.redirectTo({
        url: '/pages/login/login'
      })
    }
  }
}

4. 使用 Vue 路由守卫(H5端)

如果是H5平台,可以使用Vue Router的守卫:

javascript 复制代码
// router.js
import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

const router = new Router({
  routes: [
    // 路由配置
  ]
})

router.beforeEach((to, from, next) => {
  if (to.meta.requiresAuth && !store.getters.isAuthenticated) {
    next('/login')
  } else {
    next()
  }
})

export default router

5. 条件编译处理多端差异

javascript 复制代码
// 拦截器中处理多端差异
uni.addInterceptor('navigateTo', {
  invoke(args) {
    #ifdef H5
    // H5特有逻辑
    #endif
    
    #ifdef APP-PLUS
    // App特有逻辑
    #endif
    
    #ifdef MP-WEIXIN
    // 微信小程序特有逻辑
    #endif
  }
})

注意事项

  1. TabBar页面 :使用 switchTab 跳转的页面无法直接拦截,需要在目标页面的 onShow 中检查
  2. 首次加载 :应用启动时的第一个页面需要在 App.vue 的 onLaunch 中检查
  3. 性能考虑:避免在拦截器中执行耗时操作
  4. 多端兼容:不同平台的路由行为可能有差异,需要测试

最佳实践建议

  1. 对于简单应用,使用全局拦截器 (uni.addInterceptor) 最为方便

  2. 对于复杂应用,推荐组合使用全局拦截和页面级检查

  3. 将权限检查逻辑封装成独立函数,便于维护和复用

  4. 对于需要登录的页面,可以在页面配置中增加元信息:

    json 复制代码
    {
      "path": "pages/user/user",
      "style": {
        "navigationBarTitleText": "个人中心",
        "requiresAuth": true
      }
    }

以上方法可以根据项目需求灵活组合使用。

相关推荐
尘世中一位迷途小书童10 分钟前
和 AI 打交道会撞见的一整串词:从大模型到 Agent、RAG、MCP、Skill,一次串清
前端·人工智能
lusklusklusk14 分钟前
Python 全局变量与局部变量区别——global 关键字、__main__ 块与作用域示例
开发语言·前端·python
产品经理爱开发32 分钟前
AxureShow(艾可秀)国内通用的html托管
前端·人工智能·html·ai编程
jktantan32 分钟前
前端也需要事务:Vue Router 乐观更新、回滚与“过期事务”
前端·javascript·vue.js
怕浪猫37 分钟前
K3.1 直追 Astra,先补 13%
前端·javascript·面试
天若有情67338 分钟前
【前端趣味项目】把防抖玩出新花样!一个带隐藏后门的毫秒级“读秒挑战”
前端·javascript·html·防抖·外挂·趣味demo·读秒挑战
Liben1 小时前
Weex开发踩坑记录
android·前端·ios
jerrywus1 小时前
AI 写的代码能跑,为什么接手的人想跑?
前端·agent·claude
山雀~1 小时前
Web 多语言(i18n)技术方案详解
前端
biu_biubiu2 小时前
我开源了 Codebook
前端·vue.js