vue 从后台获取菜单数据,生成菜单

一、后端接口对接配置

1.

配置后台接口

2.

为使配置生效,在index中引入menu

二、前端vue菜单生成

1.创建菜单所在页面(HomeView.vue),代码如下:

<template>
	<!-- 系统整体页面布局 -->
	<el-container class="el-container">
	  <!-- 页面头部区域 高度默认60px -->
	  <el-header class="el-header">
		<!-- 应用名称 -->
	      <span>废物回收中心</span>
	  </el-header>
	  <el-container>
	    <!-- 左侧菜单栏部分 -->
	    <el-aside class="el-aside">
			  <el-scrollbar>
				  <el-menu class="el-menu"
					   background-color="#32323a"
					   :unique-opened="true"
					   :default-active="$route.path"
					   text-color="#ffffff"
					   router>
				    <MenuTree :menuList="menuList"></MenuTree>
				  </el-menu>
			  </el-scrollbar>
	    </el-aside>
	    <!-- 右侧主题页面内容展示 -->
	    <el-main class="el-mian">
			  <!-- 路由页面 -->
			  <router-view></router-view>
	    </el-main>
	  </el-container>
	</el-container>
</template>
<script>
import MenuTree from '@/views/MenuTree.vue';
import { generateRoutes } from '@/utils/index';

export default {
  components: {
    MenuTree
  },
  data() {
    return {
      menuList: [
        {
            id:1,
            parentid:'0',
            name:'系统主页',
            icon:'HomeFilled',
            url:'/homepage',
          },
          {
            id:2,
            parentid:'0',
            name:'学生管理',
            icon:'UserFilled',
            children:[
                {
                    id:3,
                    parentid:'2',
                    name:'信息管理',
                    icon:'',
                    children:[
                        {
                            id:4,
                            parentid:'2',
                            name:'密码修改',
                            icon:'',
                            url:'/password'
                        }
                    ]
                },
                {
                    id:5,
                    parentid:'2',
                    name:'成绩管理',
                    icon:'',
                    url:'/grade',
                }
            ]
          },
          {
            id:6,
            parentid:'0',
            name:'课程管理',
            icon:'List',
            url:'/course',
          }
        ]
    }
  },
  mounted() {
      
    },
    methods: {
      
    }
}
</script>
<style>
/*铺满屏幕,没有边距*/
.el-container {
  padding: 0px;
  margin: 0px;
  height: 100wh;
}	
.el-header {
/* 顶部部分的高度(默认60px) */
  background-color: #0077d5;
  color: #FFFFFF;
  font-size: 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 60px;
}
.el-aside {
  width: 200px;
  background-color: #32323a;
  min-height: calc(100vh - 60px);
}
.el-menu {
  min-height:100%;
}
.el-menu span {
  margin-left: 10px;
}
.el-mian {
  background-color: #eaedf1;
  padding: 0px;
  margin: 0px;
  height:calc(100vh - 60px);
}		
</style>

2.创建菜单页面(MenuTree.vue),代码如下:

<template>
    <div>
      <template v-for="(item) in menuList">
          <!-- 有次级菜单的,则展开子选项-->
          <el-sub-menu v-if="item.children && item.children.length>0" :key="item.menuId" :index="item.menuId">
            <template #title>
              <el-icon v-if="item.menuIcon!=''"><component :is="item.menuIcon" /></el-icon>
              <span :class="[item.menuPid ?'activespan':'disactivesapn']">{{item.menuName}}</span>
            </template>
            <!-- 递归,实现无限级展开 -->
            <MenuTree :menuList="item.children"></MenuTree>
          </el-sub-menu>
          <!-- 没有次级菜单的 -->
          <el-menu-item  v-if="!item.children" :key="item.menuId" :index="item.menuUrl">
              <el-icon v-if="item.menuIcon!=''"><component :is="item.menuIcon" /></el-icon>
              <span :class="[item.menuPid==0 ?'activespan':'disactivesapn']">{{item.menuName}}</span>
          </el-menu-item>
      </template>
    </div>
  </template>
  <script>
  import {
      HomeFilled,
      UserFilled,
      List
      } from "@element-plus/icons-vue";
  export default {
    props:{
        menuList:{
            type:Array,
            default(){
                return []
            }
        }
    },
    name: 'MenuTree',
    components: {
        HomeFilled,
        UserFilled,
        List
    },
    methods: {
    }
  }
  </script>
  <style scoped>
  .activespan{
      font-size: 15px !important;
  }
  .disactivesapn{
      margin-left: 20px;
      font-size: 15px !important;
  }
  /* 菜单栏选中后背景色 */
  .el-menu-item {
      color: #ffffff;
  } 
  .el-menu-item.is-active {
      color: #55aaff;
  }	
  </style>

三、对接菜单数据

调用后台接口,获取菜单数据,为前端菜单变量赋值,

调用位置(HomeView.vue

备注:getMenu(后台数据接口),toTree(数据格式转换)

mounted() {
      this.getMenu()
    },
    methods: {
      getMenu: function() { // 从后台获取菜单列表
        let _this = this;
        _this.loading = true;
        _this.$store
            .dispatch("getMenuList")
            .then(response => {
              _this.loading = false;
              let code = response.data.code;
              let results = response.data.data;
              if (code == 200) {
                _this.menuList = this.totree(results)
                _this.$store.commit('SET_MENULIST', results);
                //generateRoutes()
                //localStorage.setItem("menu",JSON.stringify(response.data.data));
              } else {
                _this.$router.push({
                  path: "/error",
                  query: { message: response.data.message }
                });
              }
            })
            .catch(() => {
              _this.loading = false;
            });

            //console.log(JSON.parse(localStorage.getItem("menu")))
            //self.menuList = JSON.parse(localStorage.getItem("menu"))
      },
      totree(data) {
        let map = {};
        let val = [];
        //生成数据对象集合
        data.forEach(it => {
          map[it.menuId] = it;
        })
        //生成结果集
        data.forEach(it => {
          const parent = map[it.menuPid];
          if (parent) {
            if (!Array.isArray(parent.children)) parent.children = [];
            parent.children.push(it);
          } else {
            val.push(it);
          }
        })
        return val;
      }
    }

四、前端路由配置

如此配置,保证打开的菜单,出现在右侧菜单位置,演示效果如下

总结:

本文只是粗浅用法,仅供参考。

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值