1. 前言
在某次日常开发中, 项目要求页面的导航菜单需要动态加载, 即菜单不能在页面上写死, 菜单上的数据由后端开发从数据库中获取返回给前端使用, 前端拿到数据后再通过解析数据最终将菜单渲染出来. 由于菜单有可能是多级的, 所以我们需要使用递归的方式, 一层一层的递归数据, 将多级菜单完整显示出来. 本篇博文借助 element UI 组件库中的 Navmenu 导航菜单组件, 将其进行改造后封装成一个多级导航菜单组件.
2. 工作流程
组件封装好之后, 由父组件调用该组件, 父组件先向后端发送请求获取菜单数据, 然后将菜单数据传递给封装好的菜单组件, 菜单组件通过解析数据, 完成组件渲染.
3. 封装菜单组件
- <template>
- <div class="navMenu">
- <el-menu class="el-menu-vertical-demo" text-color="#fff" active-text-color="#ffd04b" router>
- <el-menu-item v-for="navMenu in navMenus" :index="navMenu.api_name" v-if="navMenu.childNodes.length == 0">
- <i class="el-icon-menu"></i>{{navMenu.api_title}}
- </el-menu-item>
- <el-submenu v-for="navMenu in navMenus" :index="navMenu.api_name" v-if="navMenu.childNodes.length != 0">
- <template slot="title"><i class="el-icon-menu"></i>{{navMenu.api_title}}</template>
- <el-menu-item :index="navMenu.api_name" v-for="item in navMenu.childNodes" :key="item.route"> <i class="el-icon-location"></i>{{item.api_title}}</el-menu-item>
- </el-submenu>
- </el-menu>
- </div>
- </template>
- <script>
- export default {
- name: "NavMenu",
- props: ['navMenus'],
- data() {
- return {}
- },
- }
- </script>
- <style scoped>
- .navMenu .el-menu> li {
- background-color: rgb(84, 92, 100);
- }
- .navMenu .el-menu span, li {
- font-weight: bold;
- border-bottom: 1px solid #dddddd;
- }
- </style>
4. 父组件调用
- <template>
- <div class="menus">
- <NavMenu :navMenus="data.menu_list"></NavMenu>
- </div>
- </template>
- <script>
- import vue from 'vue'
- import {Menu, Submenu, MenuItem, MenuItemGroup,Tree} from 'element-ui';
- import NavMenu from './Navmenu'
- import VueResource from 'vue-resource'
- Vue.use(Menu);
- Vue.use(Submenu);
- Vue.use(MenuItem);
- Vue.use(MenuItemGroup);
- Vue.use(Tree);
- Vue.use(VueResource)
- export default {
- name: 'mian',
- components:{NavMenu},
- methods: {
- handleSelect:function () {
- }
- },
- beforeCreate: function () {
- // 父组件加载之前先发请求菜单数据
- this.$http.get('/menu/').then(function(response){
- console.log(response)
- this.data=response.body;
- },function(err){
- console.log(err);
- })
- }
- }
- </script>
- <style>
- .menus {
- width: 250px;
- position: absolute;
- left: 0;
- bottom: 0;
- top: 75px;
- border-right: 1px solid #dddddd;
- background-color: rgb(84, 92, 100);
- text-align: center;
- overflow-y: scroll;
- }
- </style>
5. 菜单数据格式示例
- {
- "menu_list":[
- {
- "title":"功能一", // 菜单项名字
- "childNodes":[ // 是否有子菜单, 若没有, 则为 []
- {
- "title":"功能一 1",
- "childNodes":[]
- }
- ]
- },
- {
- "title":"功能二",
- "childNodes":[]
- },
- {
- "title":"功能三",
- "childNodes":[]
- },
- {
- "title":"功能四",
- "childNodes":[]
- }
- ]
- }
6. 效果演示
(完)
来源: http://www.bubuko.com/infodetail-2805327.html