fix(Menu.vue): 版本导致菜单图标无法选择问题修复

This commit is contained in:
郝先瑞
2022-03-07 23:57:02 +08:00
parent 065e9bc127
commit e2edfecafd

View File

@@ -1,13 +1,11 @@
<template> <template>
<div class="component-container"> <div class="component-container">
<!-- 搜索表单 --> <!-- 搜索表单 -->
<el-form <el-form ref="queryFormRef" :model="queryParams" :inline="true">
ref="queryFormRef"
:model="queryParams"
:inline="true"
>
<el-form-item> <el-form-item>
<el-button type="success" :icon="Plus" @click="handleAdd">新增</el-button> <el-button type="success" :icon="Plus" @click="handleAdd"
>新增</el-button
>
</el-form-item> </el-form-item>
<el-form-item prop="name"> <el-form-item prop="name">
@@ -15,11 +13,13 @@
v-model="queryParams.name" v-model="queryParams.name"
placeholder="菜单名称" placeholder="菜单名称"
clearable clearable
@keyup.enter.native="handleQuery" @keyup.enter="handleQuery"
/> />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button> <el-button type="primary" :icon="Search" @click="handleQuery"
>搜索</el-button
>
<el-button :icon="Refresh" @click="resetQuery">重置</el-button> <el-button :icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
@@ -30,20 +30,23 @@
:data="menuList" :data="menuList"
row-key="id" row-key="id"
highlight-current-row highlight-current-row
:tree-props="{children: 'children', hasChildren: 'hasChildren'}" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
@row-click="handleRowClick" @row-click="handleRowClick"
border border
> >
<el-table-column label="菜单名称"> <el-table-column label="菜单名称">
<template #default="scope"> <template #default="scope">
<svg-icon color='#333' :icon-class="scope.row.icon?scope.row.icon:'build'"/> <svg-icon
color="#333"
:icon-class="scope.row.icon ? scope.row.icon : 'build'"
/>
{{ scope.row.name }} {{ scope.row.name }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="状态" align="center" width="100"> <el-table-column label="状态" align="center" width="100">
<template #default="scope"> <template #default="scope">
<el-tag v-if="scope.row.visible===1" type="success">显示</el-tag> <el-tag v-if="scope.row.visible === 1" type="success">显示</el-tag>
<el-tag v-else type="info">隐藏</el-tag> <el-tag v-else type="info">隐藏</el-tag>
</template> </template>
</el-table-column> </el-table-column>
@@ -76,11 +79,7 @@
</el-table> </el-table>
<!-- 弹窗表单 --> <!-- 弹窗表单 -->
<el-dialog <el-dialog :title="dialog.title" v-model="dialog.visible" width="750px">
:title="dialog.title"
v-model="dialog.visible"
width="750px"
>
<el-form <el-form
ref="dataFormRef" ref="dataFormRef"
:model="formData" :model="formData"
@@ -96,7 +95,7 @@
</el-form-item> </el-form-item>
<el-form-item label="菜单名称" prop="name"> <el-form-item label="菜单名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入菜单名称"/> <el-input v-model="formData.name" placeholder="请输入菜单名称" />
</el-form-item> </el-form-item>
<el-form-item label="是否外链"> <el-form-item label="是否外链">
@@ -107,7 +106,7 @@
</el-form-item> </el-form-item>
<el-form-item v-if="isExternalPath" label="外链地址" prop="path"> <el-form-item v-if="isExternalPath" label="外链地址" prop="path">
<el-input v-model="formData.path" placeholder="请输入外链完整路径"/> <el-input v-model="formData.path" placeholder="请输入外链完整路径" />
</el-form-item> </el-form-item>
<el-form-item v-if="!isExternalPath" label="页面路径" prop="component"> <el-form-item v-if="!isExternalPath" label="页面路径" prop="component">
@@ -116,37 +115,44 @@
placeholder="system/user/index" placeholder="system/user/index"
style="width: 95%" style="width: 95%"
> >
<template v-if="formData.parentId!=0" #prepend>src/views/</template> <template v-if="formData.parentId != 0" #prepend
<template v-if="formData.parentId!=0" #append>.vue</template> >src/views/</template
>
<template v-if="formData.parentId != 0" #append>.vue</template>
</el-input> </el-input>
<el-tooltip effect="dark" <el-tooltip
effect="dark"
content="请输入组件路径,如果是父组件填写 Layout 即可" content="请输入组件路径,如果是父组件填写 Layout 即可"
placement="right"> placement="right"
<i class="el-icon-info" style="margin-left: 10px;color:darkseagreen"></i> >
<i
class="el-icon-info"
style="margin-left: 10px; color: darkseagreen"
></i>
</el-tooltip> </el-tooltip>
</el-form-item> </el-form-item>
<el-form-item label="菜单图标"> <el-form-item label="图标" prop="icon">
<el-popover <el-popover placement="bottom-start" :width="570" trigger="click" v-model:visible="iconSelectVisible" >
placement="bottom-start" <icon-select
:width="540" ref="iconSelectRef"
v-model:visible="showChooseIcon" @selected="selected"
trigger="click" />
@show="showSelectIcon"
>
<icon-select ref="iconSelectRef" @selected="selected"/>
<template #reference> <template #reference>
<el-input v-model="formData.icon" placeholder="点击选择图标" readonly> <el-input
v-model="formData.icon"
placeholder="点击选择图标"
readonly
@click="iconSelectVisible = true"
>
<template #prefix> <template #prefix>
<svg-icon <svg-icon
v-if="formData.icon" :icon-class="formData.icon ? formData.icon : 'color'"
:icon-class="formData.icon"
class="el-input__icon" class="el-input__icon"
style="margin:auto" style="margin: auto"
color="#999" color="#999"
/> />
<i v-else class="el-icon-search el-input__icon"/>
</template> </template>
</el-input> </el-input>
</template> </template>
@@ -161,11 +167,20 @@
</el-form-item> </el-form-item>
<el-form-item label="排序" prop="sort"> <el-form-item label="排序" prop="sort">
<el-input-number v-model="formData.sort" style="width: 100px" controls-position="right" :min="0"/> <el-input-number
v-model="formData.sort"
style="width: 100px"
controls-position="right"
:min="0"
/>
</el-form-item> </el-form-item>
<el-form-item label="跳转路径"> <el-form-item label="跳转路径">
<el-input v-model="formData.redirect" placeholder="请输入跳转路径" maxlength="50"/> <el-input
v-model="formData.redirect"
placeholder="请输入跳转路径"
maxlength="50"
/>
</el-form-item> </el-form-item>
</el-form> </el-form>
@@ -180,20 +195,28 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import {listTableMenus, getMenuDetail, listTreeSelectMenus, addMenu, deleteMenus, updateMenu} from "@/api/system/menu"; import {
import {Search, Plus, Edit, Refresh, Delete} from '@element-plus/icons-vue' listTableMenus,
import {ElForm, ElMessage, ElMessageBox} from "element-plus"; getMenuDetail,
import {reactive, ref, unref, onMounted, toRefs} from "vue"; listTreeSelectMenus,
import SvgIcon from '@/components/SvgIcon/index.vue'; addMenu,
import TreeSelect from '@/components/TreeSelect/index.vue'; deleteMenus,
import IconSelect from '@/components/IconSelect/index.vue'; updateMenu,
import {isExternal} from '@/utils/validate' } from "@/api/system/menu";
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
import { ElForm, ElMessage, ElMessageBox } from "element-plus";
import { reactive, ref, unref, onMounted, toRefs } from "vue";
import { isExternal } from "@/utils/validate";
const emit = defineEmits(['menuClick']) import SvgIcon from "@/components/SvgIcon/index.vue";
import TreeSelect from "@/components/TreeSelect/index.vue";
import IconSelect from "@/components/IconSelect/index.vue";
const emit = defineEmits(["menuClick"]);
const iconSelectRef = ref(null); const iconSelectRef = ref(null);
const queryFormRef = ref(ElForm) const queryFormRef = ref(ElForm);
const dataFormRef = ref(ElForm) const dataFormRef = ref(ElForm);
const state = reactive({ const state = reactive({
loading: true, loading: true,
@@ -206,41 +229,35 @@ const state = reactive({
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
name: undefined name: undefined,
}, },
menuList: [], menuList: [],
total: 0, total: 0,
dialog: { dialog: {
title: '', title: "",
visible: false visible: false,
}, },
formData: { formData: {
id: undefined, id: undefined,
parentId: 0, parentId: 0,
name: '', name: "",
visible: 1, visible: 1,
icon: '', icon: "",
sort: 1, sort: 1,
component: 'Layout', component: "Layout",
path: '', path: "",
redirect: '' redirect: "",
}, },
rules: { rules: {
parentId: [ parentId: [{ required: true, message: "请选择顶级菜单", trigger: "blur" }],
{required: true, message: '请选择顶级菜单', trigger: 'blur'} name: [{ required: true, message: "请输入菜单名称", trigger: "blur" }],
], component: [{ required: true, message: "请输入页面路径", trigger: "blur" }],
name: [
{required: true, message: '请输入菜单名称', trigger: 'blur'}
],
component: [
{required: true, message: '请输入页面路径', trigger: 'blur'}
]
}, },
menuOptions: [] as any[], menuOptions: [] as any[],
currentRow: undefined, currentRow: undefined,
showChooseIcon: false, isExternalPath: false,
isExternalPath: false iconSelectVisible: false,
}) });
const { const {
loading, loading,
@@ -254,159 +271,156 @@ const {
rules, rules,
menuOptions, menuOptions,
isExternalPath, isExternalPath,
showChooseIcon iconSelectVisible,
} = toRefs(state) } = toRefs(state);
/** /**
* 查询 * 查询
*/ */
function handleQuery() { function handleQuery() {
// 重置父组件 // 重置父组件
emit('menuClick', null) emit("menuClick", null);
state.loading = true state.loading = true;
listTableMenus(state.queryParams).then(response => { listTableMenus(state.queryParams).then((response) => {
const {data, total} = response as any const { data, total } = response as any;
state.menuList = data state.menuList = data;
state.total = total state.total = total;
state.loading = false state.loading = false;
}) });
} }
/** /**
* 加载菜单下拉树 * 加载菜单下拉树
*/ */
async function loadTreeSelectMenuOptions() { async function loadTreeSelectMenuOptions() {
const menuOptions: any[] = [] const menuOptions: any[] = [];
await listTreeSelectMenus().then(response => { await listTreeSelectMenus().then((response) => {
const menuOption = {id: 0, label: '顶级菜单', children: response.data} const menuOption = { id: 0, label: "顶级菜单", children: response.data };
menuOptions.push(menuOption) menuOptions.push(menuOption);
state.menuOptions = menuOptions state.menuOptions = menuOptions;
}) });
} }
/** /**
* 重置查询 * 重置查询
*/ */
function resetQuery() { function resetQuery() {
const queryForm = unref(queryFormRef) const queryForm = unref(queryFormRef);
queryForm.resetFields() queryForm.resetFields();
handleQuery() handleQuery();
} }
function handleSelectionChange(selection: any) { function handleSelectionChange(selection: any) {
state.ids = selection.map((item: any) => item.id) state.ids = selection.map((item: any) => item.id);
state.single = selection.length !== 1 state.single = selection.length !== 1;
state.multiple = !selection.length state.multiple = !selection.length;
} }
function handleRowClick(row: any) { function handleRowClick(row: any) {
state.currentRow = JSON.parse(JSON.stringify(row)) state.currentRow = JSON.parse(JSON.stringify(row));
emit('menuClick', row) emit("menuClick", row);
} }
async function handleAdd(row: any) { async function handleAdd(row: any) {
await loadTreeSelectMenuOptions() await loadTreeSelectMenuOptions();
state.dialog = { state.dialog = {
title: '添加菜单', title: "添加菜单",
visible: true, visible: true,
} };
if (row.id) { if (row.id) {
// 行点击新增 // 行点击新增
state.formData.parentId = row.id state.formData.parentId = row.id;
if (row.id == 0) { if (row.id == 0) {
state.formData.component = 'Layout' state.formData.component = "Layout";
} else { } else {
state.formData.component = '' state.formData.component = "";
} }
} else { } else {
if (state.currentRow) { if (state.currentRow) {
// 工具栏新增 // 工具栏新增
state.formData.parentId = (state.currentRow as any).id state.formData.parentId = (state.currentRow as any).id;
state.formData.component = '' state.formData.component = "";
} else { } else {
state.formData.parentId = 0 state.formData.parentId = 0;
state.formData.component = 'Layout' state.formData.component = "Layout";
} }
} }
} }
async function handleUpdate(row: any) { async function handleUpdate(row: any) {
await loadTreeSelectMenuOptions() await loadTreeSelectMenuOptions();
state.dialog = { state.dialog = {
title: '修改菜单', title: "修改菜单",
visible: true visible: true,
} };
const id = row.id || state.ids const id = row.id || state.ids;
getMenuDetail(id).then(response => { getMenuDetail(id).then((response) => {
state.formData = response.data state.formData = response.data;
const path = state.formData.path as string const path = state.formData.path as string;
state.isExternalPath = isExternal(path); state.isExternalPath = isExternal(path);
}) });
} }
function submitForm() { function submitForm() {
const dataForm = unref(dataFormRef) const dataForm = unref(dataFormRef);
dataForm.validate((valid: any) => { dataForm.validate((valid: any) => {
if (valid) { if (valid) {
if (state.formData.id) { if (state.formData.id) {
updateMenu(state.formData.id, state.formData).then(response => { updateMenu(state.formData.id, state.formData).then((response) => {
ElMessage.success('修改成功') ElMessage.success("修改成功");
state.dialog.visible = false state.dialog.visible = false;
handleQuery() handleQuery();
}) });
} else { } else {
addMenu(state.formData).then(response => { addMenu(state.formData).then((response) => {
ElMessage.success('新增成功') ElMessage.success("新增成功");
state.dialog.visible = false state.dialog.visible = false;
handleQuery() handleQuery();
}) });
} }
} }
}) });
} }
function handleDelete(row: any) { function handleDelete(row: any) {
const ids = [row.id || state.ids].join(',') const ids = [row.id || state.ids].join(",");
ElMessageBox.confirm('确认删除已选中的数据项?', '警告', { ElMessageBox.confirm("确认删除已选中的数据项?", "警告", {
confirmButtonText: '确定', confirmButtonText: "确定",
cancelButtonText: '取消', cancelButtonText: "取消",
type: 'warning' type: "warning",
}).then(() => {
deleteMenus(ids).then(() => {
ElMessage.success('删除成功')
handleQuery()
}) })
}).catch(() => .then(() => {
ElMessage.info('已取消删除') deleteMenus(ids).then(() => {
) ElMessage.success("删除成功");
handleQuery();
});
})
.catch(() => ElMessage.info("已取消删除"));
} }
// 重置表单 // 重置表单
function resetForm() { function resetForm() {
dataFormRef.value.resetFields() dataFormRef.value.resetFields();
} }
function cancel() { function cancel() {
state.dialog.visible = false state.dialog.visible = false;
resetForm() resetForm();
} }
function showSelectIcon() { function showIconSelect(){
(iconSelectRef as any).value.reset(); state.iconSelectVisible = true;
state.showChooseIcon = true;
} }
function selected(name: string) { function selected(name: string) {
state.formData.icon = name; state.formData.icon = name;
state.showChooseIcon = false; state.iconSelectVisible=false
} }
onMounted(() => { onMounted(() => {
handleQuery() handleQuery();
}) });
</script> </script>
<style scoped> <style scoped>
</style> </style>