feat: pageModal组件,添加二级弹窗与使用案例

This commit is contained in:
超凡
2025-04-21 22:12:58 +08:00
parent 9e47f25520
commit 4b1614952b
7 changed files with 331 additions and 229 deletions

View File

@@ -1,5 +1,7 @@
import UserAPI, { type UserForm } from "@/api/system/user.api";
import type { IModalConfig } from "@/components/CURD/types";
import DeptAPI from "@/api/system/dept.api";
import RoleAPI from "@/api/system/role.api";
const modalConfig: IModalConfig<UserForm> = {
permPrefix: "sys:user",
@@ -45,7 +47,7 @@ const modalConfig: IModalConfig<UserForm> = {
{
label: "所属部门",
prop: "deptId",
rules: [{ required: true, message: "所属部门不能为空", trigger: "blur" }],
rules: [{ required: true, message: "所属部门不能为空", trigger: "change" }],
type: "tree-select",
attrs: {
placeholder: "请选择所属部门",
@@ -54,17 +56,22 @@ const modalConfig: IModalConfig<UserForm> = {
"check-strictly": true,
"render-after-expand": false,
},
async initFn(formItem) {
// 注意:如果initFn函数不是箭头函数,this会指向此配置项对象,那么也就可以用this来替代形参formItem
formItem.attrs.data = await DeptAPI.getOptions();
},
},
{
type: "custom",
label: "性别",
prop: "gender",
initialValue: 1,
attrs: { style: { width: "100%" } },
},
{
label: "角色",
prop: "roleIds",
rules: [{ required: true, message: "用户角色不能为空", trigger: "blur" }],
rules: [{ required: true, message: "用户角色不能为空", trigger: "change" }],
type: "select",
attrs: {
placeholder: "请选择",
@@ -72,6 +79,9 @@ const modalConfig: IModalConfig<UserForm> = {
},
options: [],
initialValue: [],
async initFn(formItem) {
formItem.options = await RoleAPI.getOptions();
},
},
{
type: "input",
@@ -115,6 +125,12 @@ const modalConfig: IModalConfig<UserForm> = {
],
initialValue: 1,
},
{
type: "custom",
label: "二级弹窗",
prop: "openModal",
slotName: "openModal",
},
],
};

View File

@@ -0,0 +1,59 @@
import { type UserForm } from "@/api/system/user.api";
import type { IModalConfig } from "@/components/CURD/types";
import DeptAPI from "@/api/system/dept.api";
const modalConfig: IModalConfig<UserForm> = {
colon: true,
dialog: {
title: "二级弹窗",
width: 500,
draggable: true,
},
form: {
labelWidth: "auto",
labelPosition: "top",
},
formItems: [
{
label: "用户名",
prop: "username",
rules: [{ required: true, message: "用户名不能为空", trigger: "blur" }],
type: "input",
attrs: { placeholder: "请输入" },
},
{
label: "用户昵称",
prop: "nickname",
rules: [{ required: true, message: "用户昵称不能为空", trigger: "blur" }],
type: "input",
attrs: { placeholder: "请输入" },
},
{
label: "所属部门",
prop: "deptId",
rules: [{ required: true, message: "所属部门不能为空", trigger: "change" }],
type: "tree-select",
attrs: {
placeholder: "请选择",
data: [],
filterable: true,
"check-strictly": true,
"render-after-expand": false,
},
async initFn(formItem) {
// 注意:如果initFn函数不是箭头函数,this会指向此配置项对象,那么也就可以用this来替代形参formItem
formItem.attrs.data = await DeptAPI.getOptions();
},
},
{
type: "custom",
label: "性别",
prop: "gender",
initialValue: 1,
attrs: { style: { width: "100%" } },
},
],
};
// 如果有异步数据会修改配置的推荐用reactive包裹而纯静态配置的可以直接导出
export default reactive(modalConfig);

View File

@@ -57,7 +57,17 @@
@submit-click="handleSubmitClick"
>
<template #gender="scope">
<Dict v-model="scope.formData[scope.prop]" code="gender" />
<Dict v-model="scope.formData[scope.prop]" code="gender" v-bind="scope.attrs" />
</template>
<template #openModal>
<el-button type="primary" @click="openSecondModal">打开二级弹窗</el-button>
</template>
</page-modal>
<!-- 二级弹窗 -->
<page-modal ref="addModalRef2" :modal-config="addModalConfig2" @custom-click="secondSubmit">
<template #gender="scope">
<Dict v-model="scope.formData[scope.prop]" code="gender" v-bind="scope.attrs" />
</template>
</page-modal>
@@ -104,9 +114,10 @@
<script setup lang="ts">
import UserAPI from "@/api/system/user.api";
import type { IObject, IOperateData } from "@/components/CURD/types";
import type { IObject, IOperateData, PageContentInstance } from "@/components/CURD/types";
import usePage from "@/components/CURD/usePage";
import addModalConfig from "./config/add";
import addModalConfig2 from "./config/add2";
import contentConfig from "./config/content";
import contentConfig2 from "./config/content2";
import editModalConfig from "./config/edit";
@@ -121,7 +132,7 @@ const {
editModalRef,
handleQueryClick,
handleResetClick,
// handleAddClick,
handleAddClick,
handleEditClick,
handleViewClick,
handleSubmitClick,
@@ -130,12 +141,8 @@ const {
handleFilterChange,
} = usePage();
// 新增
async function handleAddClick() {
addModalRef.value?.setModalVisible();
// 加载下拉数据源,建议在初始化配置项 initFn 中加载,避免多次请求
// addModalConfig.formItems[2]!.attrs!.data = await DeptAPI.getOptions();
}
const addModalRef2 = ref();
// 其他工具栏
function handleToolbarClick(name: string) {
console.log(name);
@@ -162,25 +169,14 @@ const handleOperateClick = (data: IObject) => {
ElMessageBox.prompt("请输入用户「" + data.row.username + "」的新密码", "重置密码", {
confirmButtonText: "确定",
cancelButtonText: "取消",
}).then(({ value }) => {
if (!value || value.length < 6) {
ElMessage.warning("密码至少需要6位字符请重新输入");
return false;
}
UserAPI.resetPassword(data.row.id, value).then(() => {
ElMessage.success("密码重置成功,新密码是:" + value);
});
});
} else if (data.name === "delete") {
ElMessageBox.confirm("确认删除?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(function () {
UserAPI.deleteByIds(data.row.id).then(() => {
ElMessage.success("删除成功");
contentRef.value?.handleRefresh(true); // 刷新列表
.then(({ value }) => {
if (!value || value.length < 6) {
ElMessage.warning("密码至少需要6位字符请重新输入");
return false;
}
UserAPI.resetPassword(data.row.id, value).then(() => {
ElMessage.success("密码重置成功,新密码是:" + value);
});
})
.catch(() => {});
@@ -198,6 +194,14 @@ const handleOperateClick2 = (data: IOperateData) => {
}
};
// 打开二级弹窗
const openSecondModal = () => {
handleAddClick(addModalRef2 as Ref<PageContentInstance>);
};
const secondSubmit = () => {
ElMessage.success("二级弹窗提交成功");
};
// 切换示例
const isA = ref(true);
</script>