Rumah  >  Artikel  >  hujung hadapan web  >  Bagaimana untuk merangkum komponen menu tanpa had Vue3 Element-plus dan el-menu

Bagaimana untuk merangkum komponen menu tanpa had Vue3 Element-plus dan el-menu

PHPz
PHPzke hadapan
2023-05-14 14:49:111356semak imbas

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

Bagaimana untuk merangkum komponen menu tanpa had Vue3 Element-plus dan el-menu
Rendering

1. Tentukan data

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: []
    }
 
]

2. Komponen mengekap

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 &#39;vue&#39;;
import type { PropType } from &#39;vue&#39;
import type {MenuItem} from &#39;@/types/lesson&#39;
export default defineComponent({
  name: &#39;MenuTree&#39;,
  props: {
    menu: {
      type: Array as unknown as PropType<any[]>,
      required: true,
      default: () => [],
    },
    defaultActive: {
      type: String as unknown as PropType<string>,
      required: true,
      default: &#39;&#39;,
    },
  },
  emits: [&#39;update-active-path&#39;,&#39;clickItem&#39;],
  setup(props, context) {
    const { menu, defaultActive } = toRefs(props);
 
    const generateSpaces = (level:string) => {
      let str = &#39;&#39;
      level.split(&#39;&#39;).filter(it=>it!=&#39;-&#39;).forEach(() => {
        str += &#39; &#39;
      })
      return str
    }
 
    const clickItemHandle = (item:MenuItem) => {
      context.emit(&#39;clickItem&#39;, 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 &#39;@/types/lesson&#39;
import menuData from &#39;./MenuData&#39;
 
const defaultActive = ref<string>(&#39;&#39;); // "1-1-1-1" 默认选中的数据
const menuList = ref(menuData)
 
const handleMenuClick = (item:MenuItem) => {
  console.log(&#39;父组件&#39;,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(&#39;-&#39;).length - a.split(&#39;-&#39;).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!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam