uni-app 路由拦截配置

MuYan2024-06-02VueVueuni-app

该文档拦截配置主要基于 cli 项目

Vue3 路由拦截配置

安装依赖

npm i uni-parse-pages uni-mini-router -D

新建配置文件

新建router/index.ts配置文件

// router/index.ts
import { createRouter } from "uni-mini-router";
import pagesJson from "@/pages.json";
import pagesJsonToRoutes from "uni-parse-pages";
import { loginPermissionCheck, isLoginPage } from "@/hooks/useRouter";

const routes = pagesJsonToRoutes(pagesJson);

const router = createRouter({
  routes: [...routes], // 路由表信息
});

export const loginJump = () => {
  router.push({
    name: "login",
    params: {},
  });
};

export const homeJump = () => {
  router.pushTab({
    name: "home",
    params: {},
  });
};

router.beforeEach((to, from, next) => {
  // console.log('to======>', to);
  // console.log('from====>', from);

  if (loginPermissionCheck(to)) {
    next(false);
    loginJump();
  }

  if (isLoginPage(to)) {
    next(false);
    homeJump();
  }

  next();
});

export default router;
  • 新建hooks/useRouter.ts 路由跳转文件
// hooks/useRouter.ts
type QueryObject = {
  [key: string]: any;
};

const getToken = () => {
  return "你的登录配置,例如:token";
};

const hasOwnProperty = (data: QueryObject, key: string) => {
  return Object.prototype.hasOwnProperty.call(data, key);
};

// 是否需要登录
const loginJudge = (obj: QueryObject) => {
  if (!obj || !hasOwnProperty(obj, "meta")) {
    return false;
  }
  const { meta } = obj;
  return hasOwnProperty(meta, "login") && meta?.login;
};

// 未登录,登录权限校验
export const loginPermissionCheck = (to: QueryObject) => {
  let check = false;
  if (loginJudge(to) && getToken()) {
    // 当前页面需要登录
    check = true;
  }
  return check;
};

// 已登录,登录相关页面校验
export const isLoginPage = (to: any) => {
  let check = false;
  if (
    hasOwnProperty(to, "meta") &&
    hasOwnProperty(to.meta, "module") &&
    to.meta.module === "login" &&
    getToken()
  ) {
    check = true;
  }
  return check;
};

/**
 * 以下内容为跳转二次封装内容
 */
export default function() {
  const instence = getCurrentInstance();

  const router = instence?.appContext.config.globalProperties.$Router;

  if (!router) {
    throw new Error("请在setup中配置$Router");
  }

  // 保留当前页面,跳转到应用内的某个页面,相当于使用 uni.navigateTo(OBJECT)
  const push = (name: string, query: QueryObject = {}) => {
    router.push({ name, params: query });
  };

  // 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面,相当于使用 uni.switchTab(OBJECT)
  const pushTab = (name: string) => {
    router.pushTab({ name });
  };

  // 关闭当前页面,跳转到应用内的某个页面,相当于使用 uni.redirectTo(OBJECT)
  const replace = (name: string, query: QueryObject = {}) => {
    router.push({ name, params: query });
  };

  // 关闭所有页面,打开到应用内的某个页面,相当于使用 uni.reLaunch(OBJECT)
  const replaceAll = (name: string, query: QueryObject = {}) => {
    router.replaceAll({ name, params: query });
  };

  // 关闭当前页面,返回上一页面或多级页面,相当于使用 uni.navigateBack(OBJECT)
  const back = (delta = 1) => {
    router.back({ delta, animationType: "pop-out" });
  };

  return {
    push,
    pushTab,
    replace,
    replaceAll,
    back,
  };
}
  • 使用
import myRouter from "@/hooks/useRouter";
const router = myRouter();
router.pushTab("home");
router.push("home", { id: 1 });
router.replace("home", { id: 1 });
router.replaceAll("home", { id: 1 });
router.back();

新建hooks/usePageRoutes.ts, 用于获取当前路由信息

// hooks/usePageRoutes.ts
export default function() {
  const pages = getCurrentPages();
  const page: any = pages[pages.length - 1];
  const instence = getCurrentInstance();
  const router = instence?.appContext.config.globalProperties.$Router;
  // 当前页面配置信息
  const currentPageRoutes = router.routes.find(
    (item: any) => item.path === `/${page.route}`
  );
  return {
    // 当前页面信息
    currentPageRoutes,
  };
}

新建 hooks/loginMixin.ts 文件

// hooks/loginMixin.ts
import type { App } from 'vue';
import usePageRoutes from '@/hooks/usePageRoutes';
import { loginPermissionCheck, isLoginPage } from '@/hooks/useRouter';
import { loginJump, homeJump } from '@/router';

export default {
  install(app: App) {
    app.mixin({
      data() {
        return {
          pageInit: true,
        };
      },
      computed: {
        $pageRouter() {
          return usePageRoutes();
        },
      },
      onLoad() {
        this.$initLoad();
      },
      onReady() {
        nextTick(() => {
          this.pageInit = false;
        });
      },
      onShow() {
        if (!this.pageInit) {
          this.$initLoad();
        }
      },
      methods: {
        $initLoad() {
          if (loginPermissionCheck(this.$pageRouter.currentPageRoutes)) {
            loginJump();
          }
          if (isLoginPage(this.$pageRouter.currentPageRoutes)) {
            homeJump();
          }
        },
      },
    });
  },
};

配置main.ts文件

import { createSSRApp } from "vue";
import App from "./App.vue";
import router from "@/router";
import loginMixin from "@/hooks/loginMixin";

// import 'default-passive-events'
export function createApp() {
  const app = createSSRApp(App);
  app.use(router);
  app.use(loginMixin);
  return {
    app,
  };
}
  • 配置 pages.json 文件
    • 登录配置,需要登录的页面就配置 "login": true
    • 登录模块,该页面属于登录相关界面就配置"module": "login"
    • 登录模块跟登录配置相斥,当前页面不能同时是登录模块又有登录配置
{
  "pages": [
    {
      "path": "pages/index/index",
      "name": "home",
      "meta": {
        // 配置当前页面是否需要登录
        "login": true
      }
    },
    {
      "path": "pages/login/index",
      "name": "login",
      "meta": {
        // 配置登录模块,用于已登录拦截,登录模块与login:true配置相斥
        "module": "login"
      }
    }
  ]
}

Vue2 路由拦截配置

...不定时更新

上次更新 2026/6/23 11:49:15
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.8