>[success] # 递归组件 ~~~ 1.递归组件的使用场景,某些时候会有层级关系数据进行返回,层级嵌套具 体层数未知,因此可以使用递归组件这种形式 ~~~ >[info] ## 用菜单组件说明递归组件 ~~~ 1.将整个菜单拆成了三个部分。第一部分最外层是个整个菜单的轮廓部分,第二部分 是可以点击的菜单部分'a-menu-item.vue',第三部分是可以收缩的部分'a-submenu.vue' 三个部分形成嵌套组成组件 ~~~ ~~~ 1.创建组件的结构目录如下: │ ├── 'components' // 存放组件文件夹 │ │ └── 'menu' // 存放菜单组件的文件夹 │ │ └─ 'a-menu.vue' // 菜单的根目录最外层 │ │ └─ 'a-menu-item.vue' // 菜单中可点击的菜单 │ │ └─ 'a-submenu.vue' // 配合a-menu-item.vue使用,最外层的总菜单 │ │ └─ 'index.js' ~~~ ![](https://box.kancloud.cn/86afdf3c41725978eb4680c9209c5c53_644x215.png) >[danger] index.js 导出三个组件 ~~~ import AMenu from './a-menu' import AMenuItem from './a-menu-item' import ASubmenu from './a-submenu' export default { AMenu, AMenuItem, ASubmenu } ~~~ >[danger] ##### a-menu.vue ~~~ 1.只需要留好插槽和固定样式 ~~~ ~~~ <template> <div class="a-menu"> <slot></slot> </div> </template> <script> export default { name: "AMenu" } </script> <style lang="less"> .a-menu{ & *{ list-style: none; } ul{ padding: 0; margin: 0; } } </style> ~~~ >[danger] ##### a-menu-item.vue ~~~ 1.需要留好菜单的插槽 ~~~ ~~~ <template> <li class="a-menu-item"> <slot></slot> </li> </template> <script> export default { name: "AMenuItem" } </script> <style lang="less"> .a-menu-item{ background: rgb(90,92,104); } </style> ~~~ >[danger] ##### a-submenu.vue ~~~ 1.需要留出两个部分,一部分是总名称,另一个部分是专门 放入 'a-menu-item.vue' 预留的插槽, 形成收缩隐藏的效果 ~~~ ~~~ <template> <ul class="a-submenu"> <!--显示名字--> <div class="a-submenu-title" @click="handleClick"> <slot name="title"></slot> <span class="shrink-icon" :style="{transform: `rotateZ(${showChild? 0:180}deg)`}">^</span> </div> <div v-show="showChild" class="a-submenu-child-box"> <slot></slot> </div> </ul> </template> <script> export default { name: "ASubmenu", data(){ return{ showChild:false } }, methods:{ handleClick(){ this.showChild = !this.showChild } }, } </script> <style lang="less"> .a-submenu{ background: rgb(33,35,39); &-title{ background: rgb(33,35,39); color: #fff; position: relative; .shrink-icon{ position: absolute; top: 0; right: 10px; } } &-child-box{ overflow: hidden; padding-left: 20px; } li{ background: rgb(33,35,39); } } </style> ~~~ >[danger] ##### 在视图中使用 ~~~ <template> <div class="menu-box"> <a-menu> <a-menu-item>111</a-menu-item> <a-menu-item>222</a-menu-item> <a-submenu> <div slot="title">333</div> <a-menu-item>3333-11</a-menu-item> <a-submenu> <div slot="title">333-22</div> <a-menu-item>3333-22-11</a-menu-item> </a-submenu> </a-submenu> </a-menu> </div> </template> <script> import menuComponents from '_c/menu' export default { name: "menuPage", components:{ ...menuComponents }, } </script> <style scoped lang="less"> .menu-box{ width: 300px; height: 400px; } </style> ~~~