|
|
|
@ -1,15 +1,20 @@
|
|
|
|
|
<template>
|
|
|
|
|
<!-- 使用 el-card 组件创建一个表单容器卡片,设置阴影效果为无 -->
|
|
|
|
|
<el-card class="form-container" shadow="never">
|
|
|
|
|
<!-- el-form 表单组件,绑定了 menu 数据对象作为表单数据模型,同时指定了表单验证规则、表单引用以及标签宽度 -->
|
|
|
|
|
<el-form :model="menu"
|
|
|
|
|
:rules="rules"
|
|
|
|
|
ref="menuFrom"
|
|
|
|
|
label-width="150px">
|
|
|
|
|
<!-- 表单项目,标签为“菜单名称:”,并指定了对应的数据验证属性 prop 为“title”,内部的输入框双向绑定 menu.title -->
|
|
|
|
|
<el-form-item label="菜单名称:" prop="title">
|
|
|
|
|
<el-input v-model="menu.title"></el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<!-- 表单项目,标签为“上级菜单:”,内部是一个下拉选择框,双向绑定 menu.parentId,设置了占位符 -->
|
|
|
|
|
<el-form-item label="上级菜单:">
|
|
|
|
|
<el-select v-model="menu.parentId"
|
|
|
|
|
placeholder="请选择菜单">
|
|
|
|
|
<!-- 通过 v-for 循环渲染下拉选项,每个选项的 key、label 和 value 分别对应 item 的 id、title 和 id,数据来源于 selectMenuList -->
|
|
|
|
|
<el-option
|
|
|
|
|
v-for="item in selectMenuList"
|
|
|
|
|
:key="item.id"
|
|
|
|
@ -18,22 +23,27 @@
|
|
|
|
|
</el-option>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<!-- 表单项目,标签为“前端名称:”,并指定了对应的数据验证属性 prop 为“name”,内部的输入框双向绑定 menu.name -->
|
|
|
|
|
<el-form-item label="前端名称:" prop="name">
|
|
|
|
|
<el-input v-model="menu.name"></el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<!-- 表单项目,标签为“前端图标:”,并指定了对应的数据验证属性 prop 为“icon”,内部包含一个输入框双向绑定 menu.icon 以及一个 svg-icon 组件,用于根据输入的图标类名显示图标 -->
|
|
|
|
|
<el-form-item label="前端图标:" prop="icon">
|
|
|
|
|
<el-input v-model="menu.icon" style="width: 80%"></el-input>
|
|
|
|
|
<svg-icon style="margin-left: 8px" :icon-class="menu.icon"></svg-icon>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<!-- 表单项目,标签为“是否显示:”,内部是一个单选按钮组,双向绑定 menu.hidden,用于选择是否显示该菜单 -->
|
|
|
|
|
<el-form-item label="是否显示:">
|
|
|
|
|
<el-radio-group v-model="menu.hidden">
|
|
|
|
|
<el-radio :label="0">是</el-radio>
|
|
|
|
|
<el-radio :label="1">否</el-radio>
|
|
|
|
|
</el-radio-group>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<!-- 表单项目,标签为“排序:”,内部的输入框双向绑定 menu.sort -->
|
|
|
|
|
<el-form-item label="排序:">
|
|
|
|
|
<el-input v-model="menu.sort"></el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<!-- 表单项目,包含两个按钮,提交按钮为主要类型(primary),点击时调用 onSubmit 方法并传入表单引用名;重置按钮在非编辑状态(!isEdit)下显示,点击时调用 resetForm 方法并传入表单引用名 -->
|
|
|
|
|
<el-form-item>
|
|
|
|
|
<el-button type="primary" @click="onSubmit('menuFrom')">提交</el-button>
|
|
|
|
|
<el-button v-if="!isEdit" @click="resetForm('menuFrom')">重置</el-button>
|
|
|
|
@ -41,113 +51,136 @@
|
|
|
|
|
</el-form>
|
|
|
|
|
</el-card>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import {fetchList, createMenu, updateMenu, getMenu} from '@/api/menu';
|
|
|
|
|
// 从 @/api/menu 模块中导入多个 API 函数,用于获取菜单列表、创建菜单、更新菜单以及获取单个菜单信息等操作
|
|
|
|
|
import {fetchList, createMenu, updateMenu, getMenu} from '@/api/menu';
|
|
|
|
|
|
|
|
|
|
// 默认的菜单对象,包含各个菜单相关属性的初始值,如标题、上级菜单 ID、前端名称、前端图标、是否隐藏、排序等
|
|
|
|
|
const defaultMenu = {
|
|
|
|
|
title: '',
|
|
|
|
|
parentId: 0,
|
|
|
|
|
name: '',
|
|
|
|
|
icon: '',
|
|
|
|
|
hidden: 0,
|
|
|
|
|
sort: 0
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const defaultMenu = {
|
|
|
|
|
title: '',
|
|
|
|
|
parentId: 0,
|
|
|
|
|
name: '',
|
|
|
|
|
icon: '',
|
|
|
|
|
hidden: 0,
|
|
|
|
|
sort: 0
|
|
|
|
|
};
|
|
|
|
|
export default {
|
|
|
|
|
name: "MenuDetail",
|
|
|
|
|
props: {
|
|
|
|
|
isEdit: {
|
|
|
|
|
type: Boolean,
|
|
|
|
|
default: false
|
|
|
|
|
export default {
|
|
|
|
|
name: "MenuDetail",
|
|
|
|
|
// 定义组件的 props 属性,接收一个名为 isEdit 的布尔类型属性,默认值为 false,用于判断当前是编辑状态还是新建状态
|
|
|
|
|
props: {
|
|
|
|
|
isEdit: {
|
|
|
|
|
type: Boolean,
|
|
|
|
|
default: false
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
// 菜单数据对象,初始化为 defaultMenu 的副本,用于存储当前操作的菜单相关数据
|
|
|
|
|
menu: Object.assign({}, defaultMenu),
|
|
|
|
|
// 用于存储上级菜单列表数据,供下拉选择框使用
|
|
|
|
|
selectMenuList: [],
|
|
|
|
|
// 表单验证规则对象,定义了菜单名称、前端名称、前端图标等字段的验证要求,如必填、长度范围等,以及触发验证的时机(如失去焦点时触发)
|
|
|
|
|
rules: {
|
|
|
|
|
title: [
|
|
|
|
|
{required: true, message: '请输入菜单名称', trigger: 'blur'},
|
|
|
|
|
{min: 2, max: 140, message: '长度在 2 到 140 个字符', trigger: 'blur'}
|
|
|
|
|
],
|
|
|
|
|
name: [
|
|
|
|
|
{required: true, message: '请输入前端名称', trigger: 'blur'},
|
|
|
|
|
{min: 2, max: 140, message: '长度在 2 到 140 个字符', trigger: 'blur'}
|
|
|
|
|
],
|
|
|
|
|
icon: [
|
|
|
|
|
{required: true, message: '请输入前端图标', trigger: 'blur'},
|
|
|
|
|
{min: 2, max: 140, message: '长度在 2 到 140 个字符', trigger: 'blur'}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
created() {
|
|
|
|
|
// 判断当前是否为编辑状态(通过 props 传入的 isEdit 属性判断)
|
|
|
|
|
if (this.isEdit) {
|
|
|
|
|
// 如果是编辑状态,调用获取单个菜单信息的 API 函数,传入从路由参数中获取的菜单 ID,成功后将获取到的菜单数据赋值给 menu 对象
|
|
|
|
|
getMenu(this.$route.query.id).then(response => {
|
|
|
|
|
this.menu = response.data;
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
// 如果不是编辑状态,将菜单数据对象重置为默认值
|
|
|
|
|
this.menu = Object.assign({}, defaultMenu);
|
|
|
|
|
}
|
|
|
|
|
// 调用获取上级菜单列表的方法,用于初始化上级菜单下拉选择框的数据
|
|
|
|
|
this.getSelectMenuList();
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
getSelectMenuList() {
|
|
|
|
|
// 调用获取菜单列表的 API 函数,传入分页相关参数(这里固定获取第一页,每页 100 条数据)
|
|
|
|
|
fetchList(0, {pageSize: 100, pageNum: 1}).then(response => {
|
|
|
|
|
// 将获取到的菜单列表数据赋值给 selectMenuList 属性,用于在下拉选择框中展示
|
|
|
|
|
this.selectMenuList = response.data.list;
|
|
|
|
|
// 在上级菜单列表数据开头插入一个默认选项,表示“无上级菜单”,方便用户选择
|
|
|
|
|
this.selectMenuList.unshift({id: 0, title: '无上级菜单'});
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
menu: Object.assign({}, defaultMenu),
|
|
|
|
|
selectMenuList: [],
|
|
|
|
|
rules: {
|
|
|
|
|
title: [
|
|
|
|
|
{required: true, message: '请输入菜单名称', trigger: 'blur'},
|
|
|
|
|
{min: 2, max: 140, message: '长度在 2 到 140 个字符', trigger: 'blur'}
|
|
|
|
|
],
|
|
|
|
|
name: [
|
|
|
|
|
{required: true, message: '请输入前端名称', trigger: 'blur'},
|
|
|
|
|
{min: 2, max: 140, message: '长度在 2 到 140 个字符', trigger: 'blur'}
|
|
|
|
|
],
|
|
|
|
|
icon: [
|
|
|
|
|
{required: true, message: '请输入前端图标', trigger: 'blur'},
|
|
|
|
|
{min: 2, max: 140, message: '长度在 2 到 140 个字符', trigger: 'blur'}
|
|
|
|
|
]
|
|
|
|
|
onSubmit(formName) {
|
|
|
|
|
// 通过表单引用调用表单的验证方法,传入一个回调函数,验证结果作为参数传入该回调函数
|
|
|
|
|
this.$refs[formName].validate((valid) => {
|
|
|
|
|
if (valid) {
|
|
|
|
|
// 如果表单验证通过,弹出确认框,询问是否提交数据
|
|
|
|
|
this.$confirm('是否提交数据', '提示', {
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
type: 'warning'
|
|
|
|
|
}).then(() => {
|
|
|
|
|
// 判断当前是否为编辑状态
|
|
|
|
|
if (this.isEdit) {
|
|
|
|
|
// 如果是编辑状态,调用更新菜单的 API 函数,传入从路由参数中获取的菜单 ID 和当前的菜单数据对象
|
|
|
|
|
// 成功后显示修改成功的提示消息,停留 1000 毫秒后返回上一页(路由操作)
|
|
|
|
|
updateMenu(this.$route.query.id, this.menu).then(response => {
|
|
|
|
|
this.$message({
|
|
|
|
|
message: '修改成功',
|
|
|
|
|
type: 'success',
|
|
|
|
|
duration: 1000
|
|
|
|
|
});
|
|
|
|
|
this.$router.back();
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
// 如果不是编辑状态,调用创建菜单的 API 函数,传入当前的菜单数据对象
|
|
|
|
|
// 成功后先重置表单字段,再调用 resetForm 方法(重置相关数据),显示提交成功的提示消息,停留 1000 毫秒后返回上一页(路由操作)
|
|
|
|
|
createMenu(this.menu).then(response => {
|
|
|
|
|
this.$refs[formName].resetFields();
|
|
|
|
|
this.resetForm(formName);
|
|
|
|
|
this.$message({
|
|
|
|
|
message: '提交成功',
|
|
|
|
|
type: 'success',
|
|
|
|
|
duration: 1000
|
|
|
|
|
});
|
|
|
|
|
this.$router.back();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
// 如果表单验证失败,显示验证失败的提示消息,停留 1000 毫秒,并返回 false 阻止后续操作
|
|
|
|
|
this.$message({
|
|
|
|
|
message: '验证失败',
|
|
|
|
|
type: 'error',
|
|
|
|
|
duration: 1000
|
|
|
|
|
});
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
created() {
|
|
|
|
|
if (this.isEdit) {
|
|
|
|
|
getMenu(this.$route.query.id).then(response => {
|
|
|
|
|
this.menu = response.data;
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
this.menu = Object.assign({}, defaultMenu);
|
|
|
|
|
}
|
|
|
|
|
resetForm(formName) {
|
|
|
|
|
// 通过表单引用调用表单的重置字段方法,重置表单所有字段
|
|
|
|
|
this.$refs[formName].resetFields();
|
|
|
|
|
// 将菜单数据对象重置为默认值
|
|
|
|
|
this.menu = Object.assign({}, defaultMenu);
|
|
|
|
|
// 重新调用获取上级菜单列表的方法,刷新上级菜单下拉选择框的数据
|
|
|
|
|
this.getSelectMenuList();
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
getSelectMenuList() {
|
|
|
|
|
fetchList(0, {pageSize: 100, pageNum: 1}).then(response => {
|
|
|
|
|
this.selectMenuList = response.data.list;
|
|
|
|
|
this.selectMenuList.unshift({id: 0, title: '无上级菜单'});
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
onSubmit(formName) {
|
|
|
|
|
this.$refs[formName].validate((valid) => {
|
|
|
|
|
if (valid) {
|
|
|
|
|
this.$confirm('是否提交数据', '提示', {
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
type: 'warning'
|
|
|
|
|
}).then(() => {
|
|
|
|
|
if (this.isEdit) {
|
|
|
|
|
updateMenu(this.$route.query.id, this.menu).then(response => {
|
|
|
|
|
this.$message({
|
|
|
|
|
message: '修改成功',
|
|
|
|
|
type: 'success',
|
|
|
|
|
duration: 1000
|
|
|
|
|
});
|
|
|
|
|
this.$router.back();
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
createMenu(this.menu).then(response => {
|
|
|
|
|
this.$refs[formName].resetFields();
|
|
|
|
|
this.resetForm(formName);
|
|
|
|
|
this.$message({
|
|
|
|
|
message: '提交成功',
|
|
|
|
|
type: 'success',
|
|
|
|
|
duration: 1000
|
|
|
|
|
});
|
|
|
|
|
this.$router.back();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
this.$message({
|
|
|
|
|
message: '验证失败',
|
|
|
|
|
type: 'error',
|
|
|
|
|
duration: 1000
|
|
|
|
|
});
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
resetForm(formName) {
|
|
|
|
|
this.$refs[formName].resetFields();
|
|
|
|
|
this.menu = Object.assign({}, defaultMenu);
|
|
|
|
|
this.getSelectMenuList();
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
|
|
|
|
/* scoped 属性表示样式仅作用于当前组件内的元素,避免样式冲突 */
|
|
|
|
|
</style>
|
|
|
|
|