左側のメニュー バーは、基本的にフロントエンド プロジェクトで発生する要件です。この記事はコンポーネントに基づいており、再帰コンポーネントの概念antd
を組み合わせて、vue
ユニバーサルな左側のメニュー バー コンポーネントをカプセル化します。メニュー ディレクトリはレベルで自由に構成できます。
プロジェクトで使用したバージョンは次のとおりです。
1.sideBar.vue
コンポーネントを実装する
<template>
<a-layout-sider v-model:collapsed="collapsed" collapsible>
<a-menu
:selectedKeys="selectedKeys"
@update:selectedKeys="updateSelectedKeys"
theme="dark"
mode="inline"
:openKeys="openKeys"
@update:openKeys="updateOpenKeys"
>
<template v-for="item in menuList" :key="item.key">
<template v-if="!item.children">
<a-menu-item :key="item.key" @click="menuItemClick(item)">
<template #icon>
<SettingOutlined />
</template>
{
{
item.title }}
</a-menu-item>
</template>
<template v-else>
<sub-menu
:key="item.key"
:menu-info="item"
@menuItemClick="menuItemClick"
></sub-menu>
</template>
</template>
</a-menu>
</a-layout-sider>
</template>
<script lang="ts" setup>
import SubMenu from './subMenu.vue';
import {
SettingOutlined } from '@ant-design/icons-vue';
import {
log } from 'console';
interface MenuItem {
key: string;
title: string;
path?: string;
icon?: string;
children?: MenuItem[];
}
interface Props {
menuList: Array<MenuItem>;
selectedKeys: string[];
openKeys: string[];
collapsed?: boolean;
}
withDefaults(defineProps<Props>(), {
collapsed: false
});
const emit = defineEmits([
'menuItemClick',
'update:selectedKeys',
'update:openKeys'
]);
const updateSelectedKeys = (...res: string[][]) => {
emit('update:selectedKeys', ...res);
};
const updateOpenKeys = (...res: string[][]) => {
emit('update:openKeys', ...res);
};
const menuItemClick = (item: MenuItem) => {
emit('menuItemClick', item);
};
</script>
2.sideBar.vue
コンポーネントで使用されるサブコンポーネントを実装しますSubMenu.vue
。サブコンポーネントは再帰コンポーネントです。
<template>
<a-sub-menu :key="menuInfo.key">
<template #icon><SettingOutlined /></template>
<template #title>{
{ menuInfo.title }}</template>
<template v-for="item in menuInfo.children" :key="item.key">
<template v-if="!item.children">
<a-menu-item :key="item.key" @click="menuItemClick(item)">
{
{
item.title }}
</a-menu-item>
</template>
<template v-else>
<sub-menu
:key="item.key"
:menu-info="item"
@menuItemClick="menuItemClick(item)"
></sub-menu>
</template>
</template>
</a-sub-menu>
</template>
<script lang="ts" setup name="SubMenu">
import {
SettingOutlined } from '@ant-design/icons-vue';
interface MenuInfo {
key: string;
title: string;
path?: string;
icon?: string;
children?: MenuInfo[];
}
defineProps<{
menuInfo: MenuInfo;
}>();
const emit = defineEmits(['menuItemClick']);
const menuItemClick = (item: MenuInfo) => {
emit('menuItemClick', item);
};
</script>
3. 使用例
<template>
<a-layout style="min-height: 100vh">
<side-bar
:menuList="menuList"
v-model:openKeys="openKeys"
v-model:selectedKeys="selectedKeys"
@menuItemClick="menuItemClick"
></side-bar>
<a-layout>
<a-layout-header style="background: #fff; padding: 0 0 0 16px">
{
{
title }}
</a-layout-header>
<a-layout-content style="margin: 0 16px"> 内容展示区 </a-layout-content>
</a-layout>
</a-layout>
</template>
<script lang="ts" setup>
import {
reactive, ref } from 'vue';
import SideBar from '../components/sideBar.vue';
interface MenuItem {
key: string;
title: string;
children?: MenuItem[];
[x: string]: any;
}
const menuList = reactive<MenuItem[]>([
{
title: 'Option',
key: 'option',
icon: '<SettingOutlined />',
children: [
{
title: 'option1',
key: 'o1'
},
{
title: 'option2',
key: 'o2'
}
]
},
{
title: 'User',
key: 'user',
children: [
{
title: 'user1',
key: 'user1'
},
{
title: 'user2',
key: 'user1',
children: [
{
title: 'user3',
key: 'user3'
}
]
}
]
},
{
title: 'Team',
key: 'team'
}
]);
const openKeys = ref<string[]>(['option', 'user']);
const selectedKeys = ref<string[]>(['option']);
const title = ref<string>('');
const menuItemClick = (item: MenuItem) => {
title.value = item.title;
};
</script>
4.エフェクト表示
5. 欠点
最終的なエフェクト表示から、カスタマイズ可能なメニュー レベルを持つユニバーサル コンポーネント機能が実装されていることがわかりますが、実装されたコードからは、各メニューの前にある小さなアイコンがまだ固定されていることがわかります。 antd コンポーネント ライブラリに付属するアイコンの使用は、動的パラメータ構成を介して実装するのは簡単ではありません。小さなアイコンを実装したい場合は、それらを構成してから動的にレンダリングすることもできます。外部の iconFont アイコン実装を導入できます。 1) iconFont アイコンを導入します。手順は次のとおりです: 参照
: Ant Design Vue では外部 IconFont アイコンが導入されていますが、この記事では詳しく説明しません; 2)次のように、それぞれアイコンを
置き換えてsidBar.vue
使用します。 ) 使用する場合、対応する型名を示す設定項目を追加できます。SubItem.vue中
icon
icon