elementui递归
递归组件的实现方式
在Element UI中实现递归组件,通常用于树形结构或嵌套数据的展示。Element UI的el-tree组件本身支持递归渲染,但若需自定义递归组件,可参考以下方法。
创建递归组件时,需明确组件的name属性,以便在模板中调用自身。例如实现一个递归菜单:

<template>
<div>
<div @click="toggle">
{{ data.label }}
</div>
<div v-show="isOpen" v-if="data.children">
<recursive-component
v-for="child in data.children"
:key="child.id"
:data="child"
/>
</div>
</div>
</template>
<script>
export default {
name: 'RecursiveComponent', // 必须定义name
props: {
data: Object
},
data() {
return {
isOpen: false
};
},
methods: {
toggle() {
this.isOpen = !this.isOpen;
}
}
};
</script>
结合Element UI组件库
若需与Element UI的组件(如el-menu)结合,可通过递归生成嵌套菜单结构:

<template>
<el-menu>
<template v-for="item in menuData">
<el-submenu
v-if="item.children"
:key="item.id"
:index="item.id.toString()"
>
<template #title>{{ item.title }}</template>
<recursive-menu :menu-data="item.children" />
</el-submenu>
<el-menu-item v-else :key="item.id" :index="item.id.toString()">
{{ item.title }}
</el-menu-item>
</template>
</el-menu>
</template>
<script>
export default {
name: 'RecursiveMenu',
props: {
menuData: Array
}
};
</script>
性能优化建议
递归组件可能导致渲染性能问题,尤其是深层嵌套时。可通过以下方式优化:
- 虚拟滚动:对大量数据使用
el-virtual-scroll(需单独引入)或第三方库如vue-virtual-scroller。 - 懒加载:在树形结构中动态加载子节点数据,参考
el-tree的lazy模式。 - 记忆化:使用
v-once或计算属性缓存已渲染节点。
动态组件与递归结合
对于需要条件切换组件类型的场景,可通过<component :is="...">实现动态递归:
<template>
<component
:is="data.type === 'group' ? 'GroupComponent' : 'ItemComponent'"
:data="data"
@event="handleEvent"
/>
</template>
<script>
import GroupComponent from './GroupComponent.vue';
import ItemComponent from './ItemComponent.vue';
export default {
components: { GroupComponent, ItemComponent },
props: {
data: Object
},
methods: {
handleEvent(payload) {
this.$emit('event', payload);
}
}
};
</script>
注意事项
- 终止条件:递归组件必须包含终止条件(如
v-if="data.children"),否则会导致无限循环。 - 作用域样式:使用
scoped样式时,递归组件的子组件可能无法继承样式,需用::v-deep穿透。 - 事件传递:递归组件的事件需通过
$emit逐层向上传递,建议使用provide/inject简化跨层级通信。






