Navigation dynamique et liaison de routage dynamique

introduction

Le système de gestion d'arrière-plan normal sera divisé en différents utilisateurs, et différents utilisateurs correspondront à différentes fonctions et différentes barres de menu de navigation, de sorte que la barre de navigation de gauche ne peut pas être écrite à mort et doit être affichée dynamiquement. Ainsi, les informations de la barre de navigation doivent être obtenues à partir de l'arrière-plan, puis affichées. Chaque sous-menu de la barre de navigation sera lié à une route, il est donc nécessaire d'implémenter une liaison de route dynamique.

1. Acquisition des données de navigation

Les données de navigation de l'utilisateur sont chargées avant d'obtenir l'itinéraire. Cette partie du code se trouve dans la section de code "Making Navigation Menu and Routing Dynamic Binding".
Obtenez les informations pertinentes de la barre de navigation en arrière-plan, comme illustré dans la figure suivante :

menuList = [{
        name: 'SysManga',//对应index
        title: '系统管理',
        icon: 'el-icon-s-operation',
        path: '',//router-link跳转路由
        component: '',
        children:  [
            {
                name: 'SysUser',
                title: '用户管理',
                icon: 'el-icon-s-custom',
                path: '/sys/user',
                component: 'User',
                children: []
            },
            {
                name: 'SysRole',
                title: '角色管理',
                icon: 'el-icon-s-custom',
                path: '/sys/role',
                component: 'Role',
                children: []
            },
            {
                name: 'SysMenu',
                title: '菜单管理',
                icon: 'el-icon-s-custom',
                path: '/sys/menu',
                component: 'Menu',
                children: []
            },

        ]
    },
        {
            name: 'SysTools',
            title: '系统工具',
            icon: 'el-icon-s-tools',
            path: '',
            component: '',
            children: [
                {
                    name: 'SysDict',
                    title: '数字字典',
                    icon: 'el-icon-s-order',
                    path: '/sys/dicts',
                    component: '',
                    children: []
                },
            ]
        },
    ]

Étant donné que la liaison de routage dynamique doit être implémentée, chaque élément de menu doit contenir les informations contenues dans l'entrée de la table de routage.
Les informations de routage sont stockées dans index.js sous le dossier du routeur.
Par exemple :

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home,
    redirect: '/index',
    children: [
      {
        path: '/index',
        name: '/index',
        component: () => import('../views/Index')
      },
     
      {
        path: '/sys/person',
        name: 'Menu',
        component: () => import('../views/Person')
      },
    ]
  },
  {
    path: '/login',
    name: 'Login',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: ()=>import('../views/Login')
  }
]

Par conséquent, les éléments de menu de la barre de navigation stockés dans notre arrière-plan doivent inclure le nom, le chemin, le composant, les éléments enfants, ainsi que certains éléments supplémentaires, tels que le titre, l'icône. Ces deux champs seront utilisés lorsqu'ils seront affichés sur le front-end.

2. Effectuez une liaison dynamique du menu de navigation et du routage.

Dans le routeur index.js implémente la navigation dynamique et la liaison de routage dynamique, router.beforeEach est le garde de navigation (le gardien de la barre de
navigation) lien de garde de navigation

2.1 Navigation dynamique

(1) Get menuList : correspondant à la liste de la barre de menus de navigation de l'utilisateur
(2) Get user permissions : si l'utilisateur peut effectuer certaines opérations
La liste des menus et les autorisations sont stockées dans le magasin. Ce projet crée un fichier séparé sous le fichier du magasin. Pour le module de menu, il nous suffit d'importer et d'importer menu.js dans index.js sous le dossier du magasin. Pour des opérations spécifiques, voir Modules de routeur modular
menu.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
//错误写法export default new Vuex.Store({})
//正确写法export default{} ,因为Store只能有一个,并且放在store下的index.js
//记得在index.js中引用该模块
export default {
    state: {
        menuList: [],
        permList: [],//权限列表
        //因为刷新页面都会执行router.beforEach函数,但是该函数只需要执行一次就可以了
        // 所以设置hasRole用来判断该函数是否执行过
        hasRole: false,
    },
    //异步操作state中的变量
    mutations: {
        setMenuList(state,menuList){
            state.menuList = menuList;
        },
        setPermList(state,permList){
            state.permList = permList;
        },
        //修改hasRole值
        changeRouteState(state,hashRole){
            state.hasRole = hashRole;
        }
     },
    actions: {
    },

}

2.2 Liaison de routage dynamique

(1) Obtenir la table de routage actuelle.
(2) Parcourez l'élément de menu menuList renvoyé par le backend et ajoutez l'élément de sous-menu à la table de routage.

a : S'il y a des sous-menus, parcourir les sous-menus.
b : La méthode personnalisée menuToRoute transforme les éléments de sous-menu en éléments de routage.
c : lorsque la route transformée existe, ajoutez-la à newRoutes.

(3) Ajouter un routage.

La partie index.js du code dans le dossier du routeur

router.beforeEach((to, from, next) => {
  //获取路由状态
  let hasRoute = store.state.menus.hasRole;
  //当hasRoute为false时,才去进行动态路由绑定,
  //若为true则认为已经绑定过,则不需要再次绑定
  if(!hasRoute){
    //此处使用的axios不是我们封装好的axios.js,
    //因为我们封装好的axios里面会在请求中添加headers所以我们在这里也要加上header
    axios.get('/sys/menu/nav',{
      headers: {
        Authorization: localStorage.getItem("token"),
      }
    }).then(res => {
      //一、动态导航
      //拿到menuList:对应用户菜单权限
      let menuList = res.data.data.nav
      console.log(menuList)
      store.commit("setMenuList",menuList)
      //拿到用户权限:用户是否能执行某些操作
      console.log(res.data.data.authorities)
      store.commit("setPermList",menuList)

      //二、动态路由绑定
      //1、获取当前路由表
      let newRoutes = router.options.routes;

      //2、遍历后端返回的菜单项,将子菜单项添加到路由表中
      res.data.data.nav.forEach(menu => {
        //2.1如果有子菜单
        if(menu.children){
          //遍历子菜单
          menu.children.forEach(item => {
            //自定义menuToRoute方法将子菜单项转为路由项
            let route = menuToRoute(item)
            //当route不为空时添加到newRoutes
            if(route){
              newRoutes[0].children.push(route)
            }
          })
        }
      })
      //3、添加路由
      console.log("newRoutes")
      console.log(newRoutes)
      router.addRoutes(newRoutes)
      //将hashRole值设为true,下次可以不用再进行路由绑定
      store.commit("changeRouteState",true)
    })

  }

  next()
})

//导航转路由方法
const menuToRoute = (menu) =>  {
 // 只有当component不为空时才转为路由
 if(menu.component){
   return{
     path: menu.path,
     name: menu.name,
     //meta中可以放一些额外之,权限就可以放在里面
     meta: {
       icon: menu.icon,
       title: menu.title
     },
     //
     component: () => import('../views/'+menu.component)
   }
 }
 return null;
}

3. Problèmes et solutions

Lorsque nous actualiserons la page, nous effectuerons une opération de liaison de navigation dynamique et de routage dynamique. En fait, elle n'a besoin d'être effectuée qu'une seule fois pour un utilisateur, nous utilisons donc une variable booléenne hasRole pour déterminer s'il s'agit de la première connexion, seule la première fois Liez la navigation dynamique et le routage dynamique, et ne liez plus la navigation dynamique et le routage dynamique lorsque la page est à nouveau actualisée. Bien sûr, hasRole est également stocké dans le magasin, tel qu'écrit par menu.js.

Je suppose que tu aimes

Origine blog.csdn.net/weixin_43424325/article/details/121332970
conseillé
Classement