递归组件的使用1. 封装简单的Menu组件一个子组件就相当于一个父组件的html标签父组件: menu-page.vue子组件: a-menu.vue、a-menu-item.vue、a-submenu.vue还有个暴露子组件的index.js先上一张最后渲染的结果:menu-page.vue<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>333-11</a-menu-item> <a-submenu> <div slot=“title”>333-22</div> <a-menu-item>333-22-1</a-menu-item> <a-menu-item>333-22-2</a-menu-item> </a-submenu> </a-submenu> </a-menu> </div></template><script>import menuComponents from ‘_c/menu’const { AMenu, AMenuItem, ASubmenu } = menuComponentsexport default { name: ‘menu_page’, components: { AMenu, AMenuItem, ASubmenu }}</script><style lang=“less”>.menu-box{ width: 300px; height: 400px;}</style>a-menu.vue<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>a-menu-item.vue<template> <div> <li class=“a-menu-item”><slot></slot></li> </div></template><script>export default { name: ‘AMenuItem’}</script><style lang=“less”>.a-menu-item{ background: red;}</style>a-submenu.vue<template> <ul class=“a-submenu”> <div class=“a-submenu-title” @click=“handClick”> <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: { handClick () { this.showChild = !this.showChild } }}</script><style lang=“less”>.a-submenu{ background: gray; color: #fff; &-title{ position: relative; .shrink-icon{ position: absolute; top: 2px; right: 10px; } } &-child-box{ overflow: hidden; padding-left: 20px; } li{ background: gray; }}</style>index.jsimport AMenu from ‘./a-menu.vue’import AMenuItem from ‘./a-menu-item.vue’import ASubmenu from ‘./a-submenu.vue’export default{ AMenu, AMenuItem, ASubmenu}2.递归组件子组件不断调用自身(需要组件有name属性),接上面组件的例子,修改menu-page.vue,新增re-subname.vuemenu-page.vue<template> <div class=“menu-box”> <a-menu> <template v-for="(amenu, index) in list"> <a-menu-item :key=“index” v-if="!amenu.children">{{amenu.title}}</a-menu-item> <re-submenu v-else :menu=“amenu” :index=“index” :key=“index”></re-submenu> </template> </a-menu> </div></template><script>import menuComponents from ‘_c/menu’import reSubmenu from ‘./re-submenu.vue’const { AMenu, AMenuItem, ASubmenu } = menuComponentsexport default { name: ‘menu_page’, data () { return { list: [ { title: ‘1111’ }, { title: ‘2222’ }, { title: ‘3333’, children: [ { title: ‘3333-1’ }, { title: ‘3333-2’, children: [ { title: ‘3333-2-1’ }, { title: ‘3333-2-2’ }, { title: ‘3333-2-3’, children: [ { title: ‘3333-2-3-1’ }, { title: ‘3333-2-3-2’ } ] } ] } ] } ] } }, components: { AMenu, AMenuItem, ASubmenu, reSubmenu }}</script><style lang=“less”>.menu-box{ width: 300px; height: 400px;}</style>re-subname.vue<template> <a-submenu> <div slot=“title”>{{ menu.title }}</div> <template v-for="(amenu, jndex) in menu.children"> <a-menu-item :key=“jndex” v-if="!amenu.children">{{amenu.title}}</a-menu-item> <re-submenu v-else :menu=“amenu” :index="${index}_${jndex}
" :key="${index}_${jndex}
"></re-submenu> </template> </a-submenu></template><script>import menuComponents from ‘_c/menu’const { AMenuItem, ASubmenu } = menuComponentsexport default { name: ‘reSubmenu’, components: { AMenuItem, ASubmenu }, props: { menu: { type: Object, default: function () { return {} } }, index: { type: Number } }}</script>