vue+quasar使用递归实现动态多级菜单

本文实例为大家分享了vue+quasar使用递归实现动态多级菜单的具体代码,供大家参考,具体内容如下

效果图:

菜单初始化入口 menu.vue,初始化侧边栏菜单组建,<my-q-menu/>才是递归开始

<template>   <q-drawer     v-model="is_hide_"     show-if-above     bordered     content-class="bg-grey-2"     :width="240"   >   <q-scroll-area class="fit">     <!-- 递归实现 循环菜单 -->     <my-q-menu/>   </q-scroll-area>   </q-drawer> </template> <script> import MyQMenu from './myQMenu' export default {   name: 'myMenu',   components: { MyQMenu },   data () {     return {       leftDrawerOpen: true        }   },   props: ['is_hide'],   computed: {     is_hide_: {       get () { return this.is_hide },    // boolean 型,用于控制侧边菜单栏是否显示       set () {}     }   }, } </script>

菜单递归入口 <my-q-menu/>,传入menuList.json菜单配置信息

参数说明

@my-router 菜单配置信息
@init-level 初始化菜单缩进大小

<template>   <div>     <!-- 动态菜单 -->     <q-list>       <my-q-menu-item :my-router="menuList" :init-level="0"/>     </q-list>   </div> </template> <script> import MyQMenuItem from './myQMenuItem' export default {   name: 'my-q-menu',   components: { MyQMenuItem },   data () {     return {       menuList: [         {           icon: 'inbox',           label: '菜单1',           children: [             {               icon: 'perm_identity',               label: '菜单1-1',               path: '/about'             },             {               icon: 'delete',               label: '菜单1-2',               children: [                 {                   icon: 'settings',                   label: '菜单2-1',                   path: '/noty'                 }               ]             }           ]         },         {           isItemLabel: true,           Label_text: 'item-label '         },         {           icon: 'feedback',           label: '菜单数据结构',           path: '/test',           hidden: false         }       ]     }   } } </script>

菜单元素递归执行体 <my-q-menu-item/>

<!--    动态菜单 item 递归实现    myRouter : 菜单列表    initLevel : 菜单初始化缩进等级    author : ths --> <template>   <div>     <div v-for="(item,index) in myRouter" :key="index">       <!-- 当菜单item标识为 ItemLabel 时,显示Label_text,不渲染为菜单 -->       <q-item-label v-if="item.isItemLabel" header class="text-weight-bold text-uppercase">         {{item.Label_text}}       </q-item-label>       <!-- 先判断当前菜单是否需要显示 -->       <div v-if="!item.hidden && !item.isItemLabel">         <!-- 当没有子菜单时,结束递归 -->         <div v-if="!item.children">           <q-expansion-item             :header-inset-level="initLevel"             expand-icon="1"             :to="item.path"             :icon="item.icon"             :label="item.label"           />         </div>         <!-- 子菜单依然存在时,继续递归 -->         <div v-else>           <q-expansion-item             expand-separator             :header-inset-level="initLevel"             :to="item.path"             :icon="item.icon"             :label="item.label"           >             <!-- 进入下一次递归 -->             <my-q-menu-item :my-router="item.children" :init-level="initLevel+0.3"/>           </q-expansion-item>         </div>       </div>     </div>   </div> </template> <script> export default {   name: 'my-q-menu-item',   data () {     return {}   },   props: ['myRouter', 'initLevel'] } </script>

菜单元素解释

menuList: [         {           icon: 'inbox',        //图标           label: '菜单1',        //label           children: [             {               icon: 'perm_identity',                  label: '菜单1-1',               path: '/about'     //路径             },             {               icon: 'delete',               label: '菜单1-2',               children: [                 {                   icon: 'settings',                   label: '菜单2-1',                   path: '/noty'                 }               ]             }           ]         },         {           isItemLabel: true,      //是否分隔栏           Label_text: 'item-label '   //分隔栏label         },         {           icon: 'feedback',           label: '菜单数据结构',           path: '/test',           hidden: false            //是否隐藏         }       ]

推荐阅读