Rumah > Artikel > hujung hadapan web > Bagaimana untuk merangkum komponen menu tanpa had Vue3 Element-plus dan el-menu
Komponen el-menu yang diberikan kepada kami dalam elemen boleh mencapai sehingga tiga peringkat sarang Jika terdapat satu lapisan data lagi, anda hanya boleh menambah satu lapisan sendiri melalui pembolehubah. ia selalunya OK. Ia tidak berfungsi, jadi kami hanya boleh merangkumnya
MenuData.ts
export default [ { id: "1", name: "第一级菜单", level: '1', child: [ { id: "11", name: "第二级菜单", level: '1-1', child: [ { id: "111", name: "第三级菜单", level: '1-1-1', child: [ { id: "1111", name: "第四级菜单", level: '1-1-1-1', child: [ { id: "11111", name: "第五级菜单", level: '1-1-1-1-1', child: [] } ] } ] }] } ] }, { id: "2", name: "第一级同级菜单", level: '2', child: [] } ]
Idea pembungkusan:
1. Kitar semula komponen anda sendiri, jika ada subset, gunakan anda komponen sendiri untuk menghantar data anak kepada diri sendiri
2. Jika tiada subset, gunakan el-menu-item
Kod berikut melaksanakan fungsi setup() dan setup syntax sugar masing-masing
persediaan gula sintaks
<template> <el-menu :default-active="defaultActive" :unique-opened="true" class="el-menu-vertical-demo" > <template v-for="item in menu"> <!-- 如果有子集 --> <template v-if="item.child && item.child.length > 0"> <el-sub-menu :key="item.id" :index="item.level" :disabled="item.meta?.disabled" :popper-append-to-body="false" > <template #title> <i :class="[item.meta?.icon]"></i> <!-- 添加空格 表示下级--> <span> {{ generateSpaces(item.level) }} </span> <span slot="title"> {{ item.name }}</span> </template> <MenuTree :menu="item.child" :defaultActive="defaultActive" @clickItem="clickItemHandle" /> </el-sub-menu> </template> <!-- 如果没有子集 --> <template v-else> <el-menu-item :key="item.id" :index="item.level" :disabled="item.meta?.disabled" :popper-append-to-body="false" @click="clickItemHandle(item)" > <i :class="[item.meta?.icon]"></i> <!-- 添加空格 表示下级--> <span> {{ generateSpaces(item.level) }} </span> <span slot="title">{{ item.name }}</span> </el-menu-item> </template> </template> </el-menu> </template> <script lang="ts" name="MenuTree" setup> // 把下面代码变成setup语法糖的形式 import type { PropType } from "vue"; import type { MenuItem } from "@/types/lesson"; // type 为了方便写成这样 可以根据自己项目设定type defineProps({ menu: { type: Array as unknown as PropType<any[]>, required: true, default: () => [], }, defaultActive: { type: String as unknown as PropType<string>, required: true, default: [], }, }); const emit = defineEmits(["update-active-path", "clickItem"]); // 返回的空格字符串 用于显示菜单层级 const generateSpaces = (level: string) => { let str = ""; level.split("") .filter((it) => it != "-") .forEach(() => { str += " "; }); return str; }; // 点击当前菜单项 const clickItemHandle = (item: MenuItem) => { emit("clickItem", item); }; </script> <style scoped lang="less"> .el-menu { width: 288px; } </style>
Fungsi persediaan
<template> <el-menu :default-active="defaultActive" :unique-opened="true" class="el-menu-vertical-demo" > <template v-for="item in menu"> <template v-if="item.child && item.child.length > 0"> <el-sub-menu :key="item.id" :index="item.level" :disabled="item.meta?.disabled" :popper-append-to-body="false" > <template #title> <i :class="[item.meta?.icon]"></i> <!-- 添加空格 表示下级--> <span> {{ generateSpaces(item.level) }} </span> <span slot="title"> {{ item.name }}</span> </template> <MenuTree :menu="item.child" :defaultActive="defaultActive" @clickItem="clickItemHandle" /> </el-sub-menu> </template> <template v-else> <el-menu-item :key="item.id" :index="item.level" :disabled="item.meta?.disabled" :popper-append-to-body="false" @click="clickItemHandle(item)" > <i :class="[item.meta?.icon]"></i> <!-- 添加空格 表示下级--> <span> {{ generateSpaces(item.level) }} </span> <span slot="title">{{ item.name }}</span> </el-menu-item> </template> </template> </el-menu> </template> <script lang="ts"> import { defineComponent, toRefs } from 'vue'; import type { PropType } from 'vue' import type {MenuItem} from '@/types/lesson' export default defineComponent({ name: 'MenuTree', props: { menu: { type: Array as unknown as PropType<any[]>, required: true, default: () => [], }, defaultActive: { type: String as unknown as PropType<string>, required: true, default: '', }, }, emits: ['update-active-path','clickItem'], setup(props, context) { const { menu, defaultActive } = toRefs(props); const generateSpaces = (level:string) => { let str = '' level.split('').filter(it=>it!='-').forEach(() => { str += ' ' }) return str } const clickItemHandle = (item:MenuItem) => { context.emit('clickItem', item) } return { clickItemHandle, menu, defaultActive, generateSpaces, } }, }); </script> <style scoped lang="less"> .el-menu { width: 288px; } </style>
jenis tidak ditambah. 🎜> 3. Gunakan komponen
<template> <MenuTree :menu="menuList" :defaultActive="defaultActive" @clickItem="handleMenuClick" :update-click="handleMenuClick" /> </template> <script setup lang="ts"> import MenuTree from "./components/MenuTree.vue"; import type {MenuItem} from '@/types/lesson' import menuData from './MenuData' const defaultActive = ref<string>(''); // "1-1-1-1" 默认选中的数据 const menuList = ref(menuData) const handleMenuClick = (item:MenuItem) => { console.log('父组件',item); }; </script>untuk menambah pembolehubah lalai -aktif
, jika anda ingin mengklik pada lapisan pertama data secara lalai pada mulanya, anda perlu mencari corak untuk mendapatkan semua peringkat, dan mengembalikannya kepada anda melalui antara muka untuk mendapatkan semua peringkat atau
Sebagai contoh, format data:
let arr = [ "1-1", "1-1-1", "1-1-1-1", "1-1-1-2", "1-1-1-3", "1-1-1-4", "1-1-1-5", "1-1-1-6", "1-1-2", "1-1-2-1" ]
Yang dikehendaki. hasilnya ialah elemen terpanjang dengan nombor paling sama 1-1-1-1
arr.sort((a,b)=> b.split('-').length - a.split('-').length)[0]
Gunakan belah untuk menghalang beberapa Rentetan ialah nombor dua digit 10 dan 11
Atas ialah kandungan terperinci Bagaimana untuk merangkum komponen menu tanpa had Vue3 Element-plus dan el-menu. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!