ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

vue3动态路由添加

2022-05-05 10:34:56  阅读:124  来源: 互联网

标签:getNewMenus token 添加 vue3 login children 路由 name


查看代码

import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
import { App } from "vue";
import Cookies from "js-cookie";
import store from "../store";
import { getAdminInfo } from "../request/http";

const router = createRouter({
  history: createWebHashHistory(),
  routes: [
    {
      path: "/login",
      name: "login",
      component: () => import("../views/login/Login.vue"),
    },
  ],
});
// 封装动态路由
const genRoutesConfig = () => {
  // 添加动态路由
  // 1.获取vuex里面的getters数据
  // 2.循环getters数据
  // 不知道修改vuex里面的数据,先将数据放去一个变量里再修改
  let getNewMenus: NewMenusType = store.getters.getNewMenus;
  // 第一个for in循环用来循环一级菜单对象
  for (let key in getNewMenus) {
    // 创建一个变量去接收你想要路由的样子,接口 RouteRecordRaw 是routes内部自带的接口类型定义,用来约束路由的
    let newRouteObj: RouteRecordRaw = {
      // 按照以前配路由的方式书写路由,只是把静态数据变成动态数据 getNewMenus[key].name是每一个一级路由的名字
      path: "/" + getNewMenus[key].name,
      name: getNewMenus[key].name,
      // router-view是在homepage里面的组件,所有的组件都是在router-view展示,所以一级路由名字怎么变其实都是在homepage而已
      component: () => import("../views/homepage/Homepage.vue"),
      // children默认值是空数组,约束好类型,一会循环把二级标签循环进去
      children: [],
    };
    // 为什么这里循环前需要判断一下呢?主要是让js识别一定会有getNewMenus[key].children这个值,其实不写问题也不是很大,严谨一些而已,毕竟上面的children是个空数组,理论上是不可能是个undefined
    if (getNewMenus[key].children) {
      // 第二个for循环是根据每个一级路由的children的数量进行循环,这里children为什么使用!号,因为是想让ts肯定为有值的,并不是可能为undefined,ts约束规则比较繁琐,方便日后维护
      for (let i = 0; i < getNewMenus[key].children!.length; i++) {
        // 二级路由规则
        // 二级路由的规则跟一级路由差不多,不同的地方有两点:1.path前面不用添加"/",因为"/"代表的是从根目录出发,而二级路由的路径是通过一级路由拼接而成的,不需要从根目录开始出发
        let subRouteObj: RouteRecordRaw = {
          path: getNewMenus[key].children![i].name,
          name: getNewMenus[key].children![i].name,
          // 2.路径的拼接,二级路由的路径是由一级路径/二级路径名字拼接而成,所以我们不能写死一级路由名字跟二级路由名字
          component: () =>
            import(
              `../views/${getNewMenus[key].name}/${
                getNewMenus[key].children![i].name
              }.vue`
            ),
        };
        // subRouteObj 是接收循环路由配置的变量,每次配置完就将它放进 newRouteObj.children这个数组里面
        newRouteObj.children!.push(subRouteObj);
      }
    }
    // console.log(newRouteObj);
    // 动态添加路由
    // 每次循环完一级路由及一级路由的children数组的二级路由的时候,就往router添加路由,直至循环结束
    router.addRoute(newRouteObj);
  }
  // 这里为什么会写两个静态数据的路由添加上去呢,而不是直接在上面写呢?是因为当客户不是通过除登录页面进去的,一律不让其他人通过直接输入url路径访问后台,毕竟后台管理系统不是对所有人公开,只有通过正规的login页面登录成功进去才行,真正让人知道进入的页面其实只有一个login,其他都是动态生成的.
  router.addRoute({
    path: "/",
    name: "homepage",
    // 一级路由界面,动态生成不让通过输入url方式进入
    component: () => import("../views/homepage/Homepage.vue"),
    // "/"重定向"index",一进来首页的内容就放去index文件里面,它其实也是属于homepage的子路由,它的数据不在vuex里面,自己生成个就好
    redirect: "/index",
    children: [
      {
        path: "index",
        name: "index",
        component: () => import("../views/index/index.vue"),
      },
    ],
  });
};
// 前置路由守卫
// 前置路由守护有什么用?
// 1.可以让数据不会因为刷新而丢失
// 2.不让直接输入url路径进入网页
// 3.通过设置条件实现各种功能
router.beforeEach((to, from, next) => {
  // console.log(to, from); //刷新后 to:/homepage from:/
  // 获取token值用来做判断条件
  const token = Cookies.get("token");
  // 重新获取当前登录用户的信息
  // 当存在token并且store.state.menus没有数据的时候(长度为0),进入
  if (token && store.state.menus.length === 0) {
    // 发起请求获取数据
    getAdminInfo().then((res) => {
      if (res.code === 200) {
        // 使用updateMenus将请求回来的数据更新到vuex里面
        store.commit("updateMenus", res.data.menus);
        // 调用封装动态路由
        genRoutesConfig();
        // 出口出去到当前页面,回到当前页面后,条件不成立不进入这条路线
        next(to);
      }
    });
    // 当存在token并且路径是从/login来的 去到/home 会进入该判断 home为不存在的页面,为的是让第一次登录进来的数据先通过这里进入,然后再去到index主页,让数据一定更新到主页上
  } else if (token && from.path === "/login" && to.path === "/home") {
    // 调用封装动态路由
    genRoutesConfig();
    // 去到index主页
    next("/index");
    // 如果不存在token并且去的路径不是/login,跳转到/login.为什么要设置这个判断呢?因为不想用户手动删除token后刷新依然在非登录页,还有就是直接跳过login页直接输入url进来的
  } else if (!token && to.path !== "/login") {
    // 去到login主页
    next("/login");
    // 当存在token并且要去到/login时候的判断,明明是通过登录页登录进来了,还在url输入/login跳转回登录页,这样会存在两个token可能会对后面有影响,也不符合逻辑,所以当有token的时候想通过url跳转打login,就让他原地踏步就好
  } else if (token && to.path === "/login") {
    // 去到当前页面
    next(from);
    // 当以上判断都不成立的时候,就实行,路由守卫一定要有next()出口的,不然一直出不去
  } else {
    next();
  }
});
// export default router
export const initRouter = (app: App<Element>) => {
  app.use(router);
};

标签:getNewMenus,token,添加,vue3,login,children,路由,name
来源: https://www.cnblogs.com/fengmoliu/p/16223752.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有