微信小程序 全局路由拦截

该博客介绍了如何在微信小程序中实现全局路由拦截,确保未登录用户被重定向到登录页面。通过在`utils/filter.js`中定义的`loginCheck`函数,对每个页面的`onLoad`生命周期进行包装,检查`userinfo`存储情况。如果用户未登录,会调用`wx.redirectTo`跳转到登录页面。这种方法可以有效控制页面访问权限。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 微信小程序 全局路由拦截

// utils/filter.js
function loginCheck(pageObj) {
  if (pageObj.onLoad) {
      let _onLoad = pageObj.onLoad;
      // 使用onLoad的话需要传递options
      pageObj.onLoad = function (options) {
          if(wx.getStorageSync('userinfo')) {
              // 获取当前页面
              let currentInstance = getPageInstance();
              _onLoad.call(currentInstance, options);

          } else {
              //跳转到登录页
              wx.redirectTo({
                  url: "/pages/login/index"
              });
          }
      }
  }
  return pageObj;
}

// 获取当前页面    
function getPageInstance() {
  var pages = getCurrentPages();
  return pages[pages.length - 1];
}

exports.loginCheck = loginCheck;

2. 在需要使用的页面 中使用就行了

/
const filter = require('../../utils/filter');
Page(filter.loginCheck({
    // ...
    onLoad: function (options) {
       // ...
    },
    // ...
}));
### 微信小程序中实现路由拦截的方法 微信小程序本身并没有像 Vue 这样的框架提供内置的 `beforeEach` 或类似的钩子函数来实现全局路由拦截功能。然而,可以通过一些技巧和自定义逻辑,在微信小程序中模拟实现路由拦截的功能。 以下是几种常见的实现方式: --- #### 方法一:通过覆盖默认的小程序导航 API 来实现路由拦截 可以重新封装微信小程序中的导航方法(如 `wx.navigateTo`, `wx.redirectTo`, `wx.reLaunch`, `wx.switchTab`, 和 `wx.navigateBack`),在这些方法被调用之前加入自己的业务逻辑(比如校验登录状态)。这种方法的核心在于替换掉原有的导航行为并增加额外的控制条件[^3]。 ```javascript // utils/routeInterceptor.js 文件 function checkLogin() { const userInfo = wx.getStorageSync('userInfo'); if (!userInfo) { return false; } return true; } module.exports = { navigateTo(url) { if (!checkLogin()) { wx.showToast({ title: '未登录', icon: 'none' }); setTimeout(() => { wx.redirectTo({ url: '/pages/login/index' // 登录页面路径 }); }, 1000); return; } wx.navigateTo({ url: url }); }, redirectTo(url) { if (!checkLogin()) { wx.showToast({ title: '未登录', icon: 'none' }); setTimeout(() => { wx.redirectTo({ url: '/pages/login/index' // 登录页面路径 }); }, 1000); return; } wx.redirectTo({ url: url }); }, reLaunch(url) { if (!checkLogin()) { wx.showToast({ title: '未登录', icon: 'none' }); setTimeout(() => { wx.reLaunch({ url: '/pages/login/index' // 登录页面路径 }); }, 1000); return; } wx.reLaunch({ url: url }); }, switchTab(url) { if (!checkLogin()) { wx.showToast({ title: '未登录', icon: 'none' }); setTimeout(() => { wx.redirectTo({ url: '/pages/login/index' // 登录页面路径 }); }, 1000); return; } wx.switchTab({ url: url }); } }; ``` 在实际项目中引入此工具类文件即可替代原有 API 的使用。 --- #### 方法二:利用 Page 构造器扩展机制完成页面级拦截 另一种常见的方式是在每个页面实例化时动态修改其生命周期方法(例如 `onLoad` 或者 `onShow`),从而达到类似的效果。这种方式适用于更细粒度的操作需求[^5]。 ```javascript // utils/pageFilter.js 工具模块 const pageFilter = (originalPageObject) => { if (typeof originalPageObject === 'function') { console.error('传入的对象应为 JSON 配置而非函数形式'); return {}; } const hasOnLoadMethod = !!originalPageObject.onLoad; if (hasOnLoadMethod && typeof originalPageObject.onLoad !== 'function') { console.warn(`原始 onLoad 不是一个合法函数`); } const newOnLoadFunction = function (...args) { const isLoggedIn = Boolean(wx.getStorageSync('userInfo')); if (!isLoggedIn) { wx.showToast({ title: '请先登录!', duration: 2000, mask: true, success(res) { wx.redirectTo({ url: '/pages/auth/login?redirectUrl=' + encodeURIComponent(this.route), }); }, }); return; } this.setData({ userLoggedIn: true }); if (this.__proto__.onLoadOriginal) { try { Reflect.apply(this.__proto__.onLoadOriginal, this, args); } catch (e) {} } }; Object.defineProperty(originalPageObject, '__proto__', { value: {}, writable: false, }); if (hasOnLoadMethod) { originalPageObject.__proto__.onLoadOriginal = originalPageObject.onLoad; delete originalPageObject.onLoad; } originalPageObject.onLoad = newOnLoadFunction; return originalPageObject; }; export default pageFilter; ``` 随后只需要在各个具体页面里应用该过滤器即可生效[^5]: ```javascript import pageFilter from '../../utils/pageFilter'; Page(pageFilter({ data: { }, onLoad(options){ } })); ``` --- #### 方法三:基于 getCurrentPages 获取当前路由栈信息 如果仅需简单的页面间跳转记录或者回退操作,则可以直接借助官方提供的 `getCurrentPages()` 接口获取完整的页面堆栈数据结构来进行分析处理[^4]。 ```javascript let pagesStack = getCurrentPages(); console.log(pagesStack); if (pagesStack.length >= 2) { let prevPageInstance = pagesStack[pagesStack.length - 2]; } ``` 以上代码片段展示了如何访问前一页的具体实例对象及其公开接口成员变量等内容[^4]。 --- ### 总结 综上所述,针对不同场景可以选择不同的解决方案。对于较为复杂的权限管理以及统一入口管控等情况推荐采用 **方法一**;而对于特定条件下才触发某些特殊动作则更适合选用 **方法二** 或者结合两者优势灵活运用;最后当仅仅关心前后端交互关系而不涉及太多复杂流程定制的时候可考虑尝试 **方法三**。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MW0309

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值