场景:项目中有一个菜单管理功能,希望在添加菜单或者修改菜单时可以有一个弹框选择一些图标
效果:点击打开弹窗,单击图标获取图标名称
// 表单弹窗
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="40%">
<el-form :model="dialogForm" :rules="rules" ref="ruleFormRef" label-width="120px">
<el-form-item prop="title" label="菜单名称:">
<el-input v-model="dialogForm.title" />
</el-form-item>
<el-form-item prop="parentId" label="上级菜单:" v-if="showParentSelect">
<el-tree-select v-model="dialogForm.parentId" :data="treeData" :check-strictly="true" :fit-input-width="true"
:props="defaultProps" popper-class="selectStyle">
</el-tree-select>
</el-form-item>
<el-form-item prop="index" label=" 路由地址:">
<el-input v-model="dialogForm.index" />
</el-form-item>
<el-form-item prop="icon" label="图标:">
<el-input resize="none" v-model="dialogForm.icon" /><el-icon :size="18"><el-icon @click="iconVisible=true"
class="menu-icon">
<Grid />
</el-icon></el-icon>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="resetForm(ruleFormRef)">取消</el-button>
<el-button type="primary" @click="toSubmit(ruleFormRef)">
确认
</el-button>
</span>
</template>
</el-dialog>
<!-- 图标选择弹窗 -->
<el-dialog v-model="iconVisible" title="选择图标" width="35%" close-on-click-modal="false" close-on-press-escape="false">
<!-- 展示图标 -->
<div class="icon-box">
<el-scrollbar height="400px">
<div v-for="(item, index) in Object.keys(Icons)" :key="index" class="icon-item" @click="copyIcon(item)">
<component :is="item"></component>
<div class="icon-name" :title="item">{{ item }}</div>
</div>
</el-scrollbar>
</div>
</el-dialog>
// 引入图标和表单实例
import * as Icons from "@element-plus/icons-vue";
import { FormInstance, FormRules } from "element-plus";
// 表单
interface AddForm {
id: Number;
icon?: string;
index: number | undefined;
title: string;
permiss: number | undefined;
subs?: AddForm[];
parentId?: number | undefined;
disabled?: boolean;
menuType: Number;
}
// 表单实例
const ruleFormRef = ref<FormInstance>();
const rules = reactive<FormRules>({
title: [
{
required: true,
message: "请输入角色名称",
trigger: "blur",
},
],
parentId: [
{
required: true,
message: "请选择父级菜单",
trigger: "blur",
},
],
index: [
{
required: true,
message: "请输入路由地址",
trigger: "blur",
},
],
});
const dialogForm = ref<AddForm>({});
// 弹窗
const dialogTitle = ref("add");
const dialogVisible = ref<boolean>(false);
const treeData = ref<MenuData[]>();
// 图标弹窗
const iconVisible = ref(false);
// 树形菜单
interface MenuData {
icon?: string;
index: string;
title: string;
permiss?: string;
subs?: MenuData[];
}
// 打开新增弹窗
const openAddModal = () => {
showParentSelect.value = true;
ruleFormRef.value?.resetFields();
dialogVisible.value = true;
dialogTitle.value = "新增菜单";
};
// 关闭弹窗重置表单
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return;
dialogVisible.value = false;
formEl.resetFields();
};
// 选择图标
const copyIcon = (name: string) => {
dialogForm.value.icon = name;
iconVisible.value = false;
};