Uniapp 路由拦截实现方法
Uniapp 提供了比微信小程序更灵活的路由拦截方式,可以通过以下几种方法实现:
1. 使用全局前置守卫(推荐)
在 main.js
或 router.js
中配置全局前置守卫:
// 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. 封装统一路由方法
// 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'
})
}
}
使用时代替原生方法:
import router from '@/utils/router'
router.navigateTo({
url: '/pages/user/user'
})
3. 使用页面生命周期拦截
在需要拦截的页面的 onLoad
或 onShow
中检查:
// 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的守卫:
// 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. 条件编译处理多端差异
// 拦截器中处理多端差异
uni.addInterceptor('navigateTo', {
invoke(args) {
#ifdef H5
// H5特有逻辑
#endif
#ifdef APP-PLUS
// App特有逻辑
#endif
#ifdef MP-WEIXIN
// 微信小程序特有逻辑
#endif
}
})
注意事项
- TabBar页面:使用
switchTab
跳转的页面无法直接拦截,需要在目标页面的onShow
中检查 - 首次加载:应用启动时的第一个页面需要在
App.vue
的onLaunch
中检查 - 性能考虑:避免在拦截器中执行耗时操作
- 多端兼容:不同平台的路由行为可能有差异,需要测试
最佳实践建议
- 对于简单应用,使用全局拦截器 (
uni.addInterceptor
) 最为方便 - 对于复杂应用,推荐组合使用全局拦截和页面级检查
- 将权限检查逻辑封装成独立函数,便于维护和复用
- 对于需要登录的页面,可以在页面配置中增加元信息:
{ "path": "pages/user/user", "style": { "navigationBarTitleText": "个人中心", "requiresAuth": true } }
以上方法可以根据项目需求灵活组合使用。