找到一个好的方法批量渲染el-icon(ElementPlus)

涉及技术栈:Vue3、TS、Element Plus

目标:用Element Plus写一个菜单(通常是在写菜单的时候要创建一个数组来用v-for遍历)

1.批量渲染el-icon

我的习惯是先创建一个interface文件夹和index.ts
​​在这里插入图片描述
再搞个叫MenuList的interface:(注意import的时候不要漏了type关键字)

import type { Component } from "vue"

export interface MenuList{
  path: string,//路由路径
  name: string,
  label: string,//显示的文字
  icon?: Component,//icon组件
  children?: MenuList[]//子菜单
}

之前找过用string类表示icon的示例,没一个成的(#`Д´)ノ
总结还是直接用Component类容易实现一些

组件内的代码: 利用刚刚的MenuList创建一个存放菜单信息的数组

script部分

import type { MenuList } from '@/interface'
import { ref } from 'vue'
import { House, Notebook } from '@element-plus/icons-vue'
//ref用作响应式数据,不用ref直接用数组也没问题
const menulist = ref<MenuList[]>([
  {
    path: '/home',
    name: 'home',
    label: '首页',
    icon: House,
  },
  {
    path: '/epochhistory',
    name: 'epochhistory',
    label: '训练记录',
    icon: Notebook,
  },
  //其他菜单选项...
])

template部分

<el-menu  mode="horizontal" :router="true">
        <el-menu-item v-for="item in menulist" :index="item.path" :key="item.path">
          <!-- ↓渲染icon的核心 -->
          <el-icon>
            <component :is="item.icon"></component>
          </el-icon>
          <!-- ↑渲染icon的核心 -->
          <span>{{ item.label }}</span>
        </el-menu-item>
</el-menu>

解释:
你在el-icon官网最底部可以看到一堆的图标,如果选择房子图标,点一下可以复制获得<el-icon><House /></el-icon>
看回代码:
<component :is="item.icon"></component>的部分正是替换了el-icon标签中间的<House />

效果图:

在这里插入图片描述

2.带子菜单的组件怎么渲染

如果你想写带子菜单的数组,建议先把menulist分成noChildernhasChildren(无子菜单有子菜单)两个新的数组,分开遍历

这里的menulist我就不加icon了,大家可以自己尝试一下改一下
script:

//有子菜单与无子菜单两种都有的menulist
const menulist = ref([
    {
        path: '/home',
        name: 'home',
        label: '首页',
    },
    {
        path: '/mall',
        name: 'mall',
        label: '商品管理',
    },
    {
        path: '/user',
        name: 'user',
        label: '用户管理',
    },
    {
        path: '/other',
        label: '其他',
        children: [
            {
                path: '/page1',
                name: 'page1',
                label: '页面1',
            },
            {
                path: '/page2',
                name: 'page2',
                label: '页面2',
            }
        ]
    }
])
//核心:把原数组分成两个数组
const noChildren = computed(() => list.value.filter(item => !item.children))
const hasChildren = computed(() => list.value.filter(item => item.children))

template:

<el-menu>
  <!-- 无子菜单 -->
  <el-menu-item v-for="item in noChildren" :index="item.path" :key="item.path">
    <span>{{ item.label }}</span>
  </el-menu-item>

  <!-- 有子菜单 -->
  <el-sub-menu v-for="item in hasChildren" :index="item.path" :key="item.path">
    <template #title>
    <!-- <el-icon><component :is="item.icon"><component /><el-icon /> -->
      <span>{{ item.label }}</span>
    </template>
    <el-menu-item-group>
      <el-menu-item
        v-for="subItem in item.children"
        :index="subItem.path"
        :key="subItem.path"
      >
      <!-- <el-icon><component :is="subItem.icon"><component /><el-icon /> -->
        <span>{{ subItem.label }}</span>
      </el-menu-item>
    </el-menu-item-group>
  </el-sub-menu>
</el-menu>

注意: 这里举的例子适用于只有一层子菜单,
如果你的要求是子菜单内还有有更小的子菜单(这里叫他子子菜单好了)
我的建议有两个:

有什么其他问题欢迎在评论区提出哦,希望这篇文章对你有所帮助(吐舌)
じゃね!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值