我的编程空间,编程开发者的网络收藏夹
学习永远不晚

vue如何从后台获取数据生成动态菜单列表

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

vue如何从后台获取数据生成动态菜单列表

1.数据准备

树形菜单基本数据很简单,只需要菜单id,菜单名称,路由地址,图标。下图中的节点id和父节点id是为了后端生成树形数据,只负责前端的话只需要拿到前面说的四个数据就行。

数据表

后端将数据转成树形结构,传给前端的数据结构如图

在这里插入图片描述

2.选择组件

我直接用element-ui的el-menu组件,结构是(这是用来注释的,完整代码在后面)

    <el-menu>
      <template v-for="(item, key) in menuList">-----前端得到的数据存放到menuList数组
        <el-submenu :key="key" v-if="item.children && item.children.length!==0" :index="item.m_url">----父级菜单,判断有子节点,index是路由跳转
          <template slot="title">----插槽
            <i :class="item.m_icon"></i>-----图标
            <span>{{ item.m_name }}</span>----菜单名称
          </template>
          <el-menu-item v-for="(val, index) in item.children" :index="val.m_url" :key="index">----二级菜单
            <template slot="title">
              <i :class="val.m_icon"></i>
              <span>{{ val.m_name }}</span>
            </template>
          </el-menu-item>
        </el-submenu>
        <el-submenu v-else :key="item.m_n_id" :index="item.m_url">没有子节点
          <template slot="title">
            <i :class="item.m_icon"></i>
            <span>{{ item.m_name }}</span>
          </template>
        </el-submenu>
      </template>
    </el-menu>

3.配置路由

跳转到那个页面是由写在router目录下的index.js的component指定的

import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export default new Router({
  // mode: 'history',
  routes: [
    {
      path: '/',
      name: 'home',
      meta: {
        key: '1'
      },
      component: () => import("@/views/home"),
      children: [{
        path: '/courseApplication', // 这个路径必须与后端传回数据的m_url字段相对应
        name: 'courseApplication',
        meta: {
          key: '1-1'
        },
        component: () => import('@/views/trainManage/courseApplication') // 要跳转的页面路径
      }]
    }
  ]
})

4.不出问题这样就可以实现动态路由了

在这里插入图片描述

5.完整代码

menu.vue

<template>
  <div class="menu">
     <el-menu
      class="el-menu-vertical-demo"
      @open="handleOpen"
      @close="handleClose"
      background-color="rgb(255,255,255)"
      text-color="rgb(28,41,89)"
      router = router
      active-text-color="rgb(28,41,89)">
      <template v-for="(item, key) in menuList">
        <el-submenu :key="key" v-if="item.children && item.children.length!==0" :index="item.m_url">
          <template slot="title">
            <i :class="item.m_icon"></i>
            <span>{{ item.m_name }}</span>
          </template>
          <el-menu-item v-for="(val, index) in item.children" :index="val.m_url" :key="index">
            <template slot="title">
              <i :class="val.m_icon"></i>
              <span>{{ val.m_name }}</span>
            </template>
          </el-menu-item>
        </el-submenu>
        <el-submenu v-else :key="item.m_n_id" :index="item.m_url">
          <template slot="title">
            <i :class="item.m_icon"></i>
            <span>{{ item.m_name }}</span>
          </template>
        </el-submenu>
      </template>
    </el-menu>
  </div>
</template>
<script>
import { mapActions } from 'vuex';
  export default {
    name: "asideItem",
    data(){
      return{
        router: true,
        isCollapse: true,
        label: false,
        menuList: []
      }
    },
    mounted() {
      this.getMenu()
    },
    methods: {
      ...mapActions([
        'getMenuList'
      ]),
      handleOpen(key, keyPath) {
        console.log(key, keyPath);
      },
      handleClose(key, keyPath) {
        console.log(key, keyPath);
      },
      labelChange: function() {
        console.log(this.label);
      },
      getMenu: function() { // 从后台获取菜单列表
        this.getMenuList().then(res => {
          if(res.errno === 0) {
            this.menuList = res.data
          } else {
            this.$message.error(res.data)
          }
        }).catch(error => { this.$message.error(error) })
      }
    }
  };
</script>
<style lang="postcss" scoped>
  .menu {
    transition: width 0.28s ease-out;
    width: 180px;
    background: rgb(255, 255, 255);
    height: calc(100vh - 46px);
    & .el-menu{
      width: 100%;
      border-right: none;
    }
    & :hover {
    }    
  }
  
</style>
<style>
.el-menu-item:hover{
  outline: 0 !important;
  background-color: rgb(232,240,255)!important;
}
.el-menu-item.is-active {
  background: rgb(210,226,255) !important;
}
.el-submenu__title:focus, .el-submenu__title:hover{
  outline: 0 !important;
  background: none !important;
}
</style>

router 下的index.js根据具体数据进行配置

import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export default new Router({
  // mode: 'history',
  routes: [
    {
      path: '/',
      name: 'home',
      meta: {
        key: '1'
      },
      component: () => import("@/views/home"),
      children: [{
        path: '/courseApplication', // 这个路径必须与后端传回数据的m_url字段相对应
        name: 'courseApplication',
        meta: {
          key: '1-1'
        },
        component: () => import('@/views/trainManage/courseApplication') // 要跳转的页面路径
      }]
    }
  ]
})

-----------------------这是分割线(以下是修改前的)-----------------------

在这里插入图片描述

将目录作为子目录添加到首页下面,可以显示出来,但是第二次点击同一个菜单时,会出现

在这里插入图片描述

地址叠加的情况,导致页面不能显示。而且先点击到别的页面也会出现这种情况

在这里插入图片描述

解决办法:在获取动态列表的时候,数据里面有url和source,不要去获取source,内层外层循环都获取url,然后在router/index 里面,path改为跟获取的url一样的内容

在这里插入图片描述

遍历菜单

添加路由

这个path主要是为了匹配菜单,最终调取页面是由component完成的。

刚开始的时候还有一个问题:

就是点击菜单栏的某一项,会全屏显示某一个页面,而不是懒加载的方式,只显示在中间部分,解决办法是将获取的路由放在跟路由下面,作为子组件呈现出来

将获取的动态菜单作为子路由添加

完整代码

<el-menu
          :default-active="this.$route.path"
          class="el-menu-vertical"
          router
          :collapse="iscollapse"
          :collapse-transition="false"
          :active-text-color="variables.menuActiveText"
          :background-color="variables.menuBg"
          :text-color="variables.menuText"
        >
          <fragment>
            <template v-for="item in menuList">
              <fragment v-if="item != null" :key="item.url">
                <el-submenu v-if="item.childMenuInfoTreeSet && item.childMenuInfoTreeSet.length > 0" :key="item.url" :index="item.url.toString()">
                  <template slot="title">
                    <i :class="item.iconcls.toString()" class="iconSize" />
                    <span slot="title">{{ item.menuName }}</span>
                  </template>
                  <el-menu-item v-for="val in item.childMenuInfoTreeSet" :key="val.title" :index="val.url.toString()">
                    <i :class="val.iconcls.toString()" class="iconSize" />
                    <span slot="title">{{ val.menuName }}</span>
                  </el-menu-item>
                </el-submenu>
                <el-menu-item v-else :key="item.url" :index="item.url.toString()">
                  <i :class="item.iconcls" class="iconSize" />
                  <span slot="title">{{ item.menuName }}</span>
                </el-menu-item>
              </fragment>
            </template>
          </fragment>
        </el-menu>

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。 

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

vue如何从后台获取数据生成动态菜单列表

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Ajax如何获取php返回json数据动态生成select下拉框

这篇文章主要介绍Ajax如何获取php返回json数据动态生成select下拉框,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!功能:根据选择不同层次,在专业下拉框中动态生成对应分类的专业。HTML:
2023-06-08

vue中如何使用echarts实现动态数据绑定及获取后端接口数据

本篇内容主要讲解“vue中如何使用echarts实现动态数据绑定及获取后端接口数据”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vue中如何使用echarts实现动态数据绑定及获取后端接口数据”
2023-07-02

编程热搜

目录