uniapp框架的全局文件:page.json全局文件,官网链接
背景:
通过封装 UniApp 的路由方法,并在封装方法中添加自定义逻辑,可以实现类似 Vue Router 的路由守卫功能。
在 UniApp 框架中,不像 Vue Router 直接支持路由守卫,但可以通过一些变通的方法来实现路由拦截和路由守卫的功能。主要的思路是通过重写或包装 UniApp 的路由跳转方法 (
uni.navigateTo
,uni.redirectTo
,uni.switchTab
,uni.reLaunch
,uni.navigateBack
) 来实现。
一、uniapp路由守卫实现的思路以及步骤
以下是如何在 UniApp 中实现路由拦截和路由守卫的示例:
步骤一:封装路由方法
首先,我们需要封装 UniApp 的路由方法,以便在每次路由跳转时执行一些自定义逻辑,比如路由守卫。
javascript
// utils/router.js
// 封装 navigateTo
function navigateTo(options) {
if (beforeEach(options.url)) {
uni.navigateTo(options);
}
}
// 封装 redirectTo
function redirectTo(options) {
if (beforeEach(options.url)) {
uni.redirectTo(options);
}
}
// 封装 switchTab
function switchTab(options) {
if (beforeEach(options.url)) {
uni.switchTab(options);
}
}
// 封装 reLaunch
function reLaunch(options) {
if (beforeEach(options.url)) {
uni.reLaunch(options);
}
}
// 封装 navigateBack
function navigateBack(options) {
if (beforeEach()) {
uni.navigateBack(options);
}
}
// 自定义路由守卫函数
function beforeEach(url) {
// 在这里添加自定义逻辑,例如权限验证
if (url.includes('/pages/protectedPage')) {
// 检查是否有权限访问受保护页面
const hasAccess = checkUserAccess();
if (!hasAccess) {
uni.showToast({
title: '您没有权限访问此页面',
icon: 'none'
});
return false;
}
}
return true;
}
// 示例:检查用户访问权限
function checkUserAccess() {
// 在这里添加具体的权限验证逻辑
// 例如检查用户是否已登录
const user = uni.getStorageSync('user');
return !!user;
}
// 导出封装的方法
export default {
navigateTo,
redirectTo,
switchTab,
reLaunch,
navigateBack
};
步骤二:在应用中使用封装的路由方法
在应用的各个页面或组件中,使用封装好的路由方法来替代原生的 uni
路由方法。
javascript
// 使用封装的路由方法
import router from '@/utils/router';
export default {
methods: {
goToProtectedPage() {
router.navigateTo({
url: '/pages/protectedPage/protectedPage'
});
},
goToHomePage() {
router.switchTab({
url: '/pages/index/index'
});
}
}
};
步骤三:全局路由拦截(可选)
如果希望在整个应用中统一进行路由拦截,可以在 App.vue
或 main.js
中统一引入和配置。
在实际项目中,可以根据需要扩展封装的方法,例如添加更多的路由守卫逻辑、全局前置守卫、后置守卫等。这样可以提高应用的安全性和用户体验。
javascript
// main.js 或 App.vue
import router from '@/utils/router';
// 将封装的路由方法挂载到全局对象
uni.$router = router;
export default {
onLaunch: function() {
// 全局路由守卫逻辑(可选)
// 可以在这里添加全局的路由拦截逻辑
}
};
完整的App.vue
html
//App.vue
<template>
<view>
<button @click="goToProtectedPage">去受保护页面</button>
<button @click="goToHomePage">去首页</button>
</view>
</template>
<script>
import router from '@/utils/router';
export default {
onLaunch: function() {
// 全局路由守卫逻辑(可选)
// 可以在这里添加全局的路由拦截逻辑
},
methods: {
goToProtectedPage() {
router.navigateTo({
url: '/pages/protectedPage/protectedPage'
});
},
goToHomePage() {
router.switchTab({
url: '/pages/index/index'
});
}
}
};
</script>
全局路由的拦截逻辑:
javascript
// 自定义封装一个路由拦截/路由守卫
function beforeEachFun(url) {
// 1. 权限验证
if (url.includes('/pages/protectedPage')) {
const hasAccess = checkUserAccess();
if (!hasAccess) {
uni.showToast({
title: '您没有权限访问此页面',
icon: 'none'
});
return false;
}
}
// 2. 用户登录状态检查
if (url.includes('/pages/userProfile')) {
const isLoggedIn = checkUserLoggedIn();
if (!isLoggedIn) {
uni.showToast({
title: '请先登录',
icon: 'none'
});
uni.navigateTo({
url: '/pages/login/login'
});
return false;
}
}
// 3. 记录页面访问日志
logPageVisit(url);
// 4. 页面访问频率限制
if (url.includes('/pages/highFrequencyPage')) {
const canAccess = checkPageAccessFrequency(url);
if (!canAccess) {
uni.showToast({
title: '访问过于频繁,请稍后再试',
icon: 'none'
});
return false;
}
}
return true;
}
代码解释:
- 权限验证:
- 在
beforeEachFun
函数中,检查即将访问的 URL 是否包含受保护页面的路径。如果是,则调用checkUserAccess
函数来检查用户是否有访问权限。- 如果用户没有权限,显示提示信息并阻止路由跳转。
- 用户登录状态检查:
- 在
beforeEachFun
函数中,检查即将访问的 URL 是否包含需要登录的页面路径。如果是,则调用checkUserLoggedIn
函数来检查用户是否已登录。- 如果用户未登录,显示提示信息并跳转到登录页面。
- 记录页面访问日志:
- 在
beforeEachFun
函数中,调用logPageVisit
函数记录用户访问的页面和时间戳。
- 页面访问频率限制:
- 在
beforeEachFun
函数中,检查即将访问的 URL 是否包含需要限制访问频率的页面路径。如果是,则调用checkPageAccessFrequency
函数检查用户访问该页面的频率。- 如果用户访问过于频繁,显示提示信息并阻止路由跳转。
二、全局路由拦截相关理论
全局路由守卫可以做的一些拦截,包括如下:
- 权限验证:检查用户是否有权限访问某些页面。
- 用户登录状态检查:验证用户是否已登录,未登录时跳转到登录页面。
- 记录页面访问日志:在每次路由跳转时记录用户访问的页面信息。
- 页面访问频率限制:限制用户在一定时间内重复访问某个页面。
其它,全局守卫封装的方法beforeEachFun()中调用的代码,涉及到的代码如下:
javascript
// 示例:检查用户访问权限
function checkUserAccess() {
const user = uni.getStorageSync('user');
return user && user.role === 'admin';
}
// 示例:检查用户登录状态
function checkUserLoggedIn() {
const user = uni.getStorageSync('user');
return !!user;
}
// 示例:记录页面访问日志
function logPageVisit(url) {
const visitLogs = uni.getStorageSync('visitLogs') || [];
visitLogs.push({ url, timestamp: Date.now() });
uni.setStorageSync('visitLogs', visitLogs);
}
// 示例:检查页面访问频率
function checkPageAccessFrequency(url) {
const visitLogs = uni.getStorageSync('visitLogs') || [];
const recentVisits = visitLogs.filter(log => log.url === url && Date.now() - log.timestamp < 60000);
return recentVisits.length < 3; // 限制在一分钟内访问同一页面的次数
}
三、uniapp和vue实现全局路由的对比
背景:
- UniApp 更适合需要跨平台开发的项目。
- Vue + vue-router 更适合构建复杂的 Web 单页面应用。
对比总结
配置方式:
- UniApp :在
pages.json
文件中配置页面路径和属性,比较简单直接。- Vue:通过 JavaScript 对象数组配置,灵活性更高。
API 和功能:
- UniApp :提供的路由 API 如
navigateTo
、redirectTo
等,简单易用,适合多平台的路由操作。- Vue :
vue-router
提供丰富的功能,如嵌套路由、路由守卫等,适合复杂的单页面应用。平台支持:
- UniApp:跨平台支持是其主要特点,能够编译到多个平台。
- Vue :主要用于 Web 应用,通过
vue-router
实现 SPA 路由。视图和组件集成:
- UniApp:通过路由 API 操作页面跳转,视图管理相对简单。
- Vue :
vue-router
能无缝集成 Vue 组件,通过<router-view>
实现组件视图的切换。
(一)、uniapp
UniApp 是一个使用 Vue 语法的跨平台框架,可以编译到多种平台(如微信小程序、H5、Android、iOS 等)。其路由系统针对多平台进行了优化,主要区别在于 API 和部分实现细节。
特点:
- 跨平台支持:UniApp 的路由系统设计成适配多平台,包括小程序、H5 和移动应用等。
- 路由配置 :在
pages.json
文件中统一配置页面路径和页面属性。- API 简单 :UniApp 提供了简单易用的路由 API,如
uni.navigateTo
、uni.redirectTo
、uni.switchTab
等。
示例:
1.在 pages.json
中配置路由:
javascript
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页"
}
},
{
"path": "pages/about/about",
"style": {
"navigationBarTitleText": "关于我们"
}
}
],
"tabBar": {
"list": [
{
"pagePath": "pages/index/index",
"text": "首页"
},
{
"pagePath": "pages/about/about",
"text": "关于"
}
]
}
}
2.使用 API 跳转页面:
javascript
// 跳转到关于页面
uni.navigateTo({
url: '/pages/about/about'
});
// 重定向到首页
uni.redirectTo({
url: '/pages/index/index'
});
// 切换到 tab 页
uni.switchTab({
url: '/pages/index/index'
});
(二)、vue+vue-router
Vue 的路由系统由 vue-router
实现,是专门为 Vue.js 设计的前端路由库,适用于单页面应用(SPA)。
特点:
- 丰富的功能 :
vue-router
提供了嵌套路由、命名路由、动态路由、路由守卫等丰富的功能。- 灵活配置:通过 JavaScript 对象数组配置路由,非常灵活。
- 视图和组件 :
vue-router
能够将路由和 Vue 组件无缝集成。
示例:
1.安装 vue-router
:npm install vue-router
2.配置路由:
javascript
import Vue from 'vue';
import Router from 'vue-router';
import Home from '@/components/Home.vue';
import About from '@/components/About.vue';
Vue.use(Router);
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
}
];
const router = new Router({
mode: 'history', // 'hash' or 'history' mode
routes
});
export default router;
3.使用路由:
javascript
<template>
<div>
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App'
};
</script>