[コンポーネント] vue3+ts プロジェクトの antd に基づいたユニバーサル左メニュー バー コンポーネントをカプセル化します。

左側のメニュー バーは、基本的にフロントエンド プロジェクトで発生する要件です。この記事はコンポーネントに基づいており、再帰コンポーネントの概念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中
ここに画像の説明を挿入します
ここに画像の説明を挿入します
iconicon
ここに画像の説明を挿入します

おすすめ

転載: blog.csdn.net/ganyingxie123456/article/details/126581705