Vue3 封装 Element Plus Menu 无限级菜单组件【建议收藏】

本文分别使用 SFC(模板方式)和 tsx 方式对 Element Plus el-menu 组件进行二次封装,实现配置化的菜单,有了配置化的菜单,后续便可以根据路由动态渲染菜单。

1 数据结构定义

1.1 菜单项数据结构

使用 element-plus el-menu 组件实现菜单,主要包括三个组件:

el-menu:整个菜单;
el-sub-menu:含有子菜单的菜单项;
el-sub-menu:没有子菜单的菜单项(最末级);

结合菜单的属性和展示效果,可以得到每个菜单项包括:菜单名称、菜单图标、菜单唯一标识、子菜单列表四个属性。于是可得到菜单项结构定义如下:

/**
 * 菜单项
 */
export interface MenuItem {
   
  /**
   * 菜单名称
   */
  title: string;
  /**
   * 菜单编码(对应 el-menu-item / el-sub-menu 组件的唯一标识 index 字段)
   */
  code: string;
  /**
   * 菜单的图标
   */
  icon?: string;
  /**
   * 子菜单
   */
  children?: MenuItem[]
}

传入 MenuItem 数组,使用该数组渲染出菜单。但有时候数据字段不一定为上面结构定义的属性名,如 菜单名称 字段,上面定义的属性为 title,但实际开发过程中后端返回的是 name,此时字段名不匹配。一种处理方式是前端开发获取到后台返回的数据后,遍历构造上述结构,由于是树形结构,遍历起来麻烦。另一种方式是由用户指定字段的属性名,分别指定菜单名称、菜单编码等分别对应用户传递数据的什么字段。所以需要再定义一个结构,由用户来配置字段名称。

1.2 菜单配置数据结构

首先定义菜单项字段配置的结构:

/**
 * 菜单项字段配置结构
 */
export interface MenuOptions {
   
  title?: string;
  code?: string;
  icon?: string;
  children?: string;
}

再定义菜单项结构默认字段名:

/**
 * 菜单项默认字段名称
 */
export const defaultMenuOptions: MenuOptions = {
   
  title: 'title',
  code: 'code',
  icon: 'icon',
  children: 'children'
}

2 使用 tsx 实现封装

2.1 tsx 基本结构

通常使用 tsx 封装组件的结构如下:

import {
    defineComponent } from 'vue'

export default defineComponent({
   
  name: 'yyg-menu',

  // 属性定义
  props: {
   
  },

  setup (props, context) {
   
    console.log(props, context)

    return () => (
      <div>yyg-menu</div>
    )
  }
})

2.2 定义 prop

首先定义两个属性:菜单的数据、菜单数据的字段名。

// 属性定义
props: {
   
  data: {
   
    type: Array as PropType<MenuItem[]>,
    required: true
  },
  menuOptions: {
   
    type: Object as PropType<MenuOptions>,
    required: false,
    default: () => ({
   })
  }
},

除了上面定义的两个属性,el-menu 中的属性我们也希望能够暴露出去使用:

image-20220916165319870

el-menu 的属性太多,一个个定义不太现实,在 tsx 中可以使用 context.attrs 来获取。

context.attrs 会返回当前组件定义的属性之外、用户传入的其他属性,也就是返回没有在 props 中定义的属性。

2.3 递归实现组件

setup递归 实现菜单的无限级渲染。封装函数 renderMenu,该函数接收一个数组,遍历数组:

  • 如果没有子节点,则使用 el-menu-item
  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员优雅哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值