当前位置: 首页 > news >正文

uniapp 如何实现路由拦截,路由守卫

uniapp框架的全局文件:page.json全局文件,官网链接

背景:

通过封装 UniApp 的路由方法,并在封装方法中添加自定义逻辑,可以实现类似 Vue Router 的路由守卫功能。

在 UniApp 框架中,不像 Vue Router 直接支持路由守卫,但可以通过一些变通的方法来实现路由拦截和路由守卫的功能。主要的思路是通过重写或包装 UniApp 的路由跳转方法 (uni.navigateTo, uni.redirectTo, uni.switchTab, uni.reLaunch, uni.navigateBack) 来实现。

一、uniapp路由守卫实现的思路以及步骤

以下是如何在 UniApp 中实现路由拦截和路由守卫的示例:

步骤一:封装路由方法

首先,我们需要封装 UniApp 的路由方法,以便在每次路由跳转时执行一些自定义逻辑,比如路由守卫。

// 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 路由方法。

// 使用封装的路由方法
import router from '@/utils/router';export default {methods: {goToProtectedPage() {router.navigateTo({url: '/pages/protectedPage/protectedPage'});},goToHomePage() {router.switchTab({url: '/pages/index/index'});}}
};

步骤三:全局路由拦截(可选)

如果希望在整个应用中统一进行路由拦截,可以在 App.vuemain.js 中统一引入和配置。

在实际项目中,可以根据需要扩展封装的方法,例如添加更多的路由守卫逻辑、全局前置守卫、后置守卫等。这样可以提高应用的安全性和用户体验。

// main.js 或 App.vue
import router from '@/utils/router';// 将封装的路由方法挂载到全局对象
uni.$router = router;export default {onLaunch: function() {// 全局路由守卫逻辑(可选)// 可以在这里添加全局的路由拦截逻辑}
};

完整的App.vue

//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>

 

全局路由的拦截逻辑:

// 自定义封装一个路由拦截/路由守卫
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;
}
 代码解释:
  1. 权限验证
  • beforeEachFun 函数中,检查即将访问的 URL 是否包含受保护页面的路径。如果是,则调用 checkUserAccess 函数来检查用户是否有访问权限。
  • 如果用户没有权限,显示提示信息并阻止路由跳转。
  1. 用户登录状态检查
  • beforeEachFun 函数中,检查即将访问的 URL 是否包含需要登录的页面路径。如果是,则调用 checkUserLoggedIn 函数来检查用户是否已登录。
  • 如果用户未登录,显示提示信息并跳转到登录页面。
  1. 记录页面访问日志
  • beforeEachFun 函数中,调用 logPageVisit 函数记录用户访问的页面和时间戳。
  1. 页面访问频率限制
  • beforeEachFun 函数中,检查即将访问的 URL 是否包含需要限制访问频率的页面路径。如果是,则调用 checkPageAccessFrequency 函数检查用户访问该页面的频率。
  • 如果用户访问过于频繁,显示提示信息并阻止路由跳转。

二、全局路由拦截相关理论 

全局路由守卫可以做的一些拦截,包括如下:

  • 权限验证:检查用户是否有权限访问某些页面。
  • 用户登录状态检查:验证用户是否已登录,未登录时跳转到登录页面。
  • 记录页面访问日志:在每次路由跳转时记录用户访问的页面信息。
  • 页面访问频率限制:限制用户在一定时间内重复访问某个页面。

其它,全局守卫封装的方法beforeEachFun()中调用的代码,涉及到的代码如下:

// 示例:检查用户访问权限
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 单页面应用。

对比总结

  1. 配置方式

    • UniApp:在 pages.json 文件中配置页面路径和属性,比较简单直接。
    • Vue:通过 JavaScript 对象数组配置,灵活性更高。
  2. API 和功能

    • UniApp:提供的路由 API 如 navigateToredirectTo 等,简单易用,适合多平台的路由操作。
    • Vuevue-router 提供丰富的功能,如嵌套路由、路由守卫等,适合复杂的单页面应用。
  3. 平台支持

    • UniApp:跨平台支持是其主要特点,能够编译到多个平台。
    • Vue:主要用于 Web 应用,通过 vue-router 实现 SPA 路由。
  4. 视图和组件集成

    • UniApp:通过路由 API 操作页面跳转,视图管理相对简单。
    • Vuevue-router 能无缝集成 Vue 组件,通过 <router-view> 实现组件视图的切换。

(一)、uniapp

UniApp 是一个使用 Vue 语法的跨平台框架,可以编译到多种平台(如微信小程序、H5、Android、iOS 等)。其路由系统针对多平台进行了优化,主要区别在于 API 和部分实现细节。

特点

  1. 跨平台支持:UniApp 的路由系统设计成适配多平台,包括小程序、H5 和移动应用等。
  2. 路由配置:在 pages.json 文件中统一配置页面路径和页面属性。
  3. API 简单:UniApp 提供了简单易用的路由 API,如 uni.navigateTouni.redirectTouni.switchTab 等。

示例

1.在 pages.json 中配置路由:
{"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 跳转页面:
// 跳转到关于页面
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)。

特点

  1. 丰富的功能vue-router 提供了嵌套路由、命名路由、动态路由、路由守卫等丰富的功能。
  2. 灵活配置:通过 JavaScript 对象数组配置路由,非常灵活。
  3. 视图和组件vue-router 能够将路由和 Vue 组件无缝集成。

示例

1.安装 vue-router:npm install vue-router
2.配置路由:
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' moderoutes
});export default router;
3.使用路由:
<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>
http://www.lryc.cn/news/400613.html

相关文章:

  • 人工智能算法工程师(中级)课程13-神经网络的优化与设计之梯度问题及优化与代码详解
  • Qt/QML学习-ComboBox
  • 微服务实战系列之玩转Docker(一)
  • Java中常见的语法糖
  • 数据库使用SSL加密连接
  • 华为OD算法题汇总
  • 服务器的rabbitmq的guest账号登不进去
  • 决策树(ID3,C4.5,C5.0,CART算法)以及条件推理决策树R语言实现
  • 文心一言《使用手册》,文心一言怎么用?
  • Spring Boot集成qwen:0.5b实现对话功能
  • GreenDao实现原理
  • Perl语言之数组
  • 写材料word和PPT
  • Centos---命令详解 vi 系统服务 网络
  • 【.NET全栈】ASP.NET开发web应用——ASP.NET中的样式、主题和母版页
  • [ruby on rails]部署时候产生ActiveRecord::PreparedStatementCacheExpired错误的原因及解决方法
  • 函数传值面试题
  • redis笔记2
  • Kafka(四) Consumer消费者
  • 前端路由手写Hash和History两种模式
  • Redis的单线程讲解与指令学习
  • 为什么MySQL会选择B+树作为索引
  • k8s secret-从环境变量里去读和从yaml文件里读取secret有什么区别?
  • Springboot+Aop用注解实现阿里云短信验证码校验,校验通过自动删除验证码缓存
  • 无线物联网新时代,RFID拣货标签跟随潮流
  • Java8 根据List实体中一个字段去重取最大值,并且根据该字段进行排序
  • 微服务经纬:Eureka驱动的分布式服务网格配置全解
  • 关于前端数据库可视化库的选择,vue3+antd+g2plot录课计划
  • linux进行redis的安装并使用RDB进行数据迁移
  • 深入理解Scikit-learn:决策树与随机森林算法详解