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

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

对比总结

  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 中配置路由:
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)。

特点

  1. 丰富的功能vue-router 提供了嵌套路由、命名路由、动态路由、路由守卫等丰富的功能。
  2. 灵活配置:通过 JavaScript 对象数组配置路由,非常灵活。
  3. 视图和组件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>
相关推荐
PleaSure乐事29 分钟前
使用Vue的props进行组件传递校验时出现 Extraneous non-props attributes的解决方案
vue.js
土豆炒马铃薯。1 小时前
【Vue】前端使用node.js对数据库直接进行CRUD操作
前端·javascript·vue.js·node.js·html5
姥姥家的饭1 小时前
uniapp 文本转语音
uni-app
赵大仁2 小时前
深入解析 Vue 3 的核心原理
前端·javascript·vue.js·react.js·ecmascript
bidepanm2 小时前
Vue.use()和Vue.component()
前端·javascript·vue.js
素**颜4 小时前
uniapp 基于xgplayer(西瓜视频) + renderjs开发,实现APP视频播放
javascript·uni-app·音视频
Ashore_4 小时前
从简单封装到数据响应:Vue如何引领开发新模式❓❗️
前端·vue.js
顽疲4 小时前
从零用java实现 小红书 springboot vue uniapp (6)用户登录鉴权及发布笔记
java·vue.js·spring boot·uni-app
&活在当下&4 小时前
ref 和 reactive 的用法和区别
前端·javascript·vue.js
云白冰5 小时前
hiprint结合vue2项目实现静默打印详细使用步骤
前端·javascript·vue.js