用 vue3 + element plus UI 帮我二次封装一个左侧侧边栏导航组件。要求:可以通过传入一个json的配置生成导航栏可以通过配置来控制是否展开是否显示图标是否显示标题是否显示子菜单是否显示子菜单的图标是否显示子菜单的标题跳转地址等。
以下是一个基本的左侧侧边栏导航组件的代码,你可以在此基础上进行二次封装,实现你的需求。
<template>
<el-menu :default-active="$route.path" class="left-menu" :collapse="isCollapse">
<template v-for="item in menuList">
<el-submenu v-if="item.children" :index="item.path">
<template #title>
<i v-if="item.icon" :class="item.icon"></i>
<span v-if="!isCollapse">{{ item.title }}</span>
</template>
<el-menu-item v-for="child in item.children" :key="child.path" :index="child.path">
<template v-if="!isCollapse">
<i v-if="child.icon" :class="child.icon"></i>
{{ child.title }}
</template>
</el-menu-item>
</el-submenu>
<el-menu-item v-else :key="item.path" :index="item.path">
<i v-if="item.icon" :class="item.icon"></i>
<span v-if="!isCollapse">{{ item.title }}</span>
</el-menu-item>
</template>
</el-menu>
</template>
<script>
import { defineComponent } from 'vue';
import { useRoute } from 'vue-router';
export default defineComponent({
name: 'LeftMenu',
props: {
menuList: {
type: Array,
default: () => [],
},
isCollapse: {
type: Boolean,
default: false,
},
},
setup(props) {
const route = useRoute();
return {
$route: route,
};
},
});
</script>
<style>
.left-menu {
width: 200px;
height: 100%;
background-color: #fff;
}
.left-menu i {
margin-right: 10px;
}
</style>
你可以在组件中添加一个 config 属性,用于接收传入的 json 配置。然后根据传入的配置来决定是否展开、是否显示图标、是否显示标题、是否显示子菜单等等。
以下是一个示例代码:
<template>
<el-menu :default-active="$route.path" class="left-menu" :collapse="isCollapse">
<template v-for="item in menuList">
<el-submenu v-if="item.children" :index="item.path" :disabled="item.disabled" :popper-append-to-body="item.popperAppendToBody" :show-timeout="item.showTimeout" :hide-timeout="item.hideTimeout" :popper-class="item.popperClass">
<template #title>
<i v-if="item.icon" :class="item.icon"></i>
<span v-if="!isCollapse">{{ item.title }}</span>
</template>
<el-menu-item v-for="child in item.children" :key="child.path" :index="child.path" :disabled="child.disabled" :popper-append-to-body="child.popperAppendToBody" :show-timeout="child.showTimeout" :hide-timeout="child.hideTimeout" :popper-class="child.popperClass">
<template v-if="!isCollapse">
<i v-if="child.icon" :class="child.icon"></i>
{{ child.title }}
</template>
</el-menu-item>
</el-submenu>
<el-menu-item v-else :key="item.path" :index="item.path" :disabled="item.disabled" :popper-append-to-body="item.popperAppendToBody" :show-timeout="item.showTimeout" :hide-timeout="item.hideTimeout" :popper-class="item.popperClass">
<i v-if="item.icon" :class="item.icon"></i>
<span v-if="!isCollapse">{{ item.title }}</span>
</el-menu-item>
</template>
</el-menu>
</template>
<script>
import { defineComponent } from 'vue';
import { useRoute } from 'vue-router';
export default defineComponent({
name: 'LeftMenu',
props: {
config: {
type: Object,
default: () => ({}),
},
isCollapse: {
type: Boolean,
default: false,
},
},
setup(props) {
const route = useRoute();
return {
$route: route,
menuList: props.config.menuList || [],
};
},
});
</script>
你可以在组件中自定义一些默认配置,例如:
const defaultConfig = {
menuList: [
{
path: '/',
title: '首页',
icon: 'el-icon-s-home',
},
{
path: '/about',
title: '关于我们',
icon: 'el-icon-info',
children: [
{
path: '/about/introduction',
title: '公司简介',
icon: 'el-icon-document',
},
{
path: '/about/contact',
title: '联系我们',
icon: 'el-icon-phone',
},
],
},
],
};
然后在组件中合并传入的配置和默认配置:
const config = {
...defaultConfig,
...props.config,
};
这样,你就可以使用如下代码调用该组件,并传入自定义的配置了:
<template>
<left-menu :config="config" :isCollapse="isCollapse" />
</template>
<script>
import LeftMenu from './LeftMenu.vue';
export default {
components: {
LeftMenu,
},
data() {
return {
isCollapse: false,
config: {
menuList: [
{
path: '/',
title: '首页',
icon: 'el-icon-s-home',
},
{
path: '/about',
title: '关于我们',
icon: 'el-icon-info',
children: [
{
path: '/about/introduction',
title: '公司简介',
icon: 'el-icon-document',
},
{
path: '/about/contact',
title: '联系我们',
icon: 'el-icon-phone',
},
],
},
],
},
};
},
};
</script>
你可以根据需要在配置中添加更多的选项,以满足你的需求
原文地址: https://www.cveoy.top/t/topic/chFI 著作权归作者所有。请勿转载和采集!