菜单树实现vue
实现 Vue 菜单树的方法
递归组件实现
使用 Vue 的递归组件特性可以轻松实现菜单树结构。递归组件允许组件在模板中调用自身,适用于树形结构的数据展示。
<template>
<ul>
<li v-for="item in menuData" :key="item.id">
{{ item.name }}
<menu-tree v-if="item.children" :menuData="item.children"></menu-tree>
</li>
</ul>
</template>
<script>
export default {
name: 'MenuTree',
props: {
menuData: {
type: Array,
required: true
}
}
}
</script>
动态路由结合
在 Vue 项目中,可以将菜单树与路由配置结合,实现动态路由加载和权限控制。通过后端返回的菜单数据生成路由配置。
// 动态生成路由
function generateRoutes(menuData) {
return menuData.map(item => {
const route = {
path: item.path,
name: item.name,
component: () => import(`@/views/${item.component}`)
}
if (item.children) {
route.children = generateRoutes(item.children)
}
return route
})
}
状态管理集成
对于复杂的菜单树应用,可以集成 Vuex 或 Pinia 进行状态管理,集中处理菜单的展开/收起状态和权限控制。
// Pinia store 示例
import { defineStore } from 'pinia'
export const useMenuStore = defineStore('menu', {
state: () => ({
menuTree: [],
expandedKeys: []
}),
actions: {
async fetchMenuData() {
const res = await api.getMenuTree()
this.menuTree = res.data
},
toggleExpand(key) {
const index = this.expandedKeys.indexOf(key)
index === -1
? this.expandedKeys.push(key)
: this.expandedKeys.splice(index, 1)
}
}
})
性能优化技巧
对于大型菜单树,可以使用虚拟滚动技术优化渲染性能,避免同时渲染过多 DOM 节点。
<template>
<RecycleScroller
:items="flattenMenuData"
:item-size="50"
key-field="id"
v-slot="{ item }"
>
<div :style="{ paddingLeft: `${item.level * 20}px` }">
{{ item.name }}
</div>
</RecycleScroller>
</template>
样式与交互增强
添加过渡动画和交互效果可以提升用户体验,使用 Vue 的过渡组件实现平滑的展开/收起动画。
<template>
<div class="menu-item">
<div @click="toggle">
{{ item.name }}
<span class="arrow" :class="{ 'arrow-down': isOpen }"></span>
</div>
<transition name="slide">
<div v-show="isOpen" class="submenu">
<menu-tree
v-for="child in item.children"
:key="child.id"
:item="child"
/>
</div>
</transition>
</div>
</template>
<style>
.slide-enter-active, .slide-leave-active {
transition: all 0.3s ease;
max-height: 500px;
}
.slide-enter, .slide-leave-to {
opacity: 0;
max-height: 0;
}
</style>






