前言:我们项目的菜单权限主要是由后台控制,前台根据后台提供的menuList进行页面展示,根据用户登录账号的不同,从而显示分配不同的权限菜单。

1,利用elementui 导航菜单组件书写结构(我们项目要求的权限菜单是三级的,具体可以根据实际情况进行修改)

 <el-submenu v-for="item in menuData" :key="item.id" :index="item.url">
            <template slot="title">
              <i class="fa icon" :class="item.icon"></i>
              <span>{{item.name}}</span>
            </template>
            <!-- 二级菜单 -->
            <template v-for="itemChild in item.items">
              <el-submenu
                v-if="itemChild.items && itemChild.items.length"
                :index="itemChild.url"
                :key="itemChild.id"
              >
                <template slot="title">
                  <i class="el-icon-menu icon"></i>
                  <span>{{itemChild.name}}</span>
                </template>
                <!-- 三级菜单 -->
                <el-menu-item
                  v-for="itemChild_Child in itemChild.items"
                  :index="itemChild_Child.url"
                  :key="itemChild_Child.id"
                >
                  <i class="el-icon-menu icon"></i>
                  <span slot="title">{{itemChild_Child.name}}</span>
                </el-menu-item>
              </el-submenu>
              <el-menu-item v-else :index="itemChild.url" :key="itemChild.id">
                <i class="el-icon-menu icon"></i>
                <span slot="title">{{itemChild.name}}</span>
              </el-menu-item>
            </template>
          </el-submenu>

2,通过vuex 存储后台返回菜单权限的数组,在router.js 中拿到vuex 中存储的数据,注册路由
2.1.在 sotre.js 中导入菜单请求接口

import { Menu} from './api/index'

2.2,初始化菜单栏,获取菜单栏数据,配置路由规则

export default new Vuex.Store({
    state: {
      newArr:JSON.parse(sessionStorage.getItem('menu')) || []   //声明一个全局变量
    },
    
    mutations: {
      // 初始化菜单栏
      initmenus(state, list) {
        var newArr = iterator_self(list.menus, []);
        function iterator_self(obj, arr) {
          if (JSON.stringify(obj) !== "{}") {
            for (var i in obj) {
              var oo = {
                "id": i,
                "name": obj[i].name,
                "url": '/'+obj[i].url,
                "items": iterator_self(obj[i].items,[])
              }
              arr.push(oo);
            }
            return arr
          }
        }
        sessionStorage.setItem('menu',JSON.stringify(newArr))
        router.push({name: '首页'})
      }
    },
    actions: {
      //获取菜单栏数据 配置路由规则
      getMenu(context, arg) {
        Menu().then(res => {
          context.commit('initmenus', res.data) 
        });
      }
    }
  })

2.3,用户登录成功后通过vuex存储后台返回的菜单路由数组
2.3.1 ,先引入store获取侧边栏菜单(在methods 方法中)

    ...mapActions(["getMenu"]),

2.3.2,请求登录接口成功后,通过vuex存储后台返回的菜单路由数组

    loginSubmit() {
      let postData = {
        username: this.username,
        password: this.password
      };
      checkUser(postData).then(res => {
        if (res.code === 200) {
          this.$message.success("登录成功");
          // 如果登录成功,存储token
          localStorage.setItem("mytoken", res.data.token);
          // 登录成功后通过vuex存储后台返回的菜单路由数组
          this.getMenu();
          // 登录成功后通过 vuex 存储用户名
          this.$store.commit("setUsername", this.username);
        } else {
          this.$message({
            type: "error",
            message: res.msg
          });
          this.username = "";
          this.password = "";
        }
      });
    }

2.4,在router.js 中调用vuex 存储的数据。进行动态路由配置

  store.state.newArr.forEach(v=>{
    v.items.forEach(item=>{
      // console.log(item.url)
      let route = {}
      route.path = item.url
      route.name = item.name
      // 使用路由懒加载拼接路由路径获取组件
      route.component = () => import(`@/views${item.url}`)
      router.options.routes[2].children.push(route)
      if(item.items&&item.items.length){
        item.items.forEach(i => {
          let r = {}
          r.path = i.url
          r.name = i.name
          r.component = () => import(`@/views${i.url}`)
          router.options.routes[2].children.push(r)
        })
      }
    })
  })
    // 注册新路由
router.addRoutes(router.options.routes)

3,在应用页面(home.vue)请求菜单接口,渲染菜单权限相关信息

     Menu().then(res => {
        if (res.code === 200) {
          var newArr = iterator_self(res.data.menus, []);
          function iterator_self(obj, arr) {
            if (JSON.stringify(obj) !== "{}") {
              for (var i in obj) {
                var oo = {
                  id: i,
                  icon: "fa-" + obj[i].icon,
                  name: obj[i].name,
                  url: "/" + obj[i].url,
                  items: iterator_self(obj[i].items, [])
                };
                arr.push(oo);
              }
            }
            return arr;
          }
          this.menuData = newArr;
        }
      });
Logo

前往低代码交流专区

更多推荐