Dialog弹窗在后台管理系统中是使用频率非常高的组件,添加和修改数据基本都会用到,本文就讲讲在vue3和ts的项目中如何封装Dialog组件,实现代码高复用

如下图,在后台管理系统中需要对数据进行添加和编辑,希望他们能共用一个弹窗,那么我们就需要对弹窗的功能进行封装。下面一起来看看在vue3+ts的项目中如何实现:

对于Dialog组件的封装,我们大致进行如下步骤实现:
其中主要的难点在于第二步,涉及组件的传值(defineProps)和组件的自定义事件(emits)。
下面来分布详细介绍:
我这里使用的是element-plus。
首先在components文件夹下新建文件DialogModal.vue 用来写这个组件
UI部分没什么难点,我这里直接贴代码了,根据自己需求进行修改:
<template>
<el-dialog
:before-close="handleClose"
v-model="show"
:title="editData ? '编辑收支信息' : '添加收支信息'"
>
<el-form
:model="formData"
ref="form"
:rules="formRules"
label-width="120px"
style="margin: 10px; width: auto"
>
<el-form-item label="收支类型">
<el-select v-model="formData.type" placeholder="收支类型">
<el-option
v-for="(formType, index) in typeList"
:key="index"
:label="formType"
:value="formType"
></el-option>
</el-select>
</el-form-item>
<el-form-item prop="describe" label="收支描述">
<el-input v-model="formData.describe" type="describe"></el-input>
</el-form-item>
<el-form-item prop="income" label="收入">
<el-input v-model="formData.income" type="income"></el-input>
</el-form-item>
<el-form-item prop="expend" label="支出">
<el-input v-model="formData.expend" type="expend"></el-input>
</el-form-item>
<el-form-item prop="cash" label="账户现金">
<el-input v-model="formData.cash" type="cash"></el-input>
</el-form-item>
<el-form-item label="备注">
<el-input v-model="formData.remark" type="textarea"></el-input>
</el-form-item>
<el-form-item class="text-right">
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" @click="handleSubmit(form)">提交</el-button>
</el-form-item>
</el-form>
</el-dialog>
</template>
有不懂的变量别着急,下面会讲
这里我们按功能分块来讲:
首先我们在list页面,
const show = ref<boolean>(false);
const editData = ref<formDataType>()
这里editData是自定有类型formDataType,从外部ts中引入的类型:
import { formDataType} from "../utils/types";
贴一下这个ts文件的代码:
export interface formDataType {
type: string;
describe: string;
income: string;
expend: string;
cash: string;
remark: string;
_id?: string;
}
const handleEdit = (row: formDataType) => {
show.value = true;
editData.value = row;
};
<DialogModal
:show="show"
:editData="editData"
/>
4.回到DialogModal组件的页面,下面我们要接收传值和监听数据
这是使用defineProps接受传值:
const props = defineProps({
show: {
type: Boolean,
},
editData: {
type: Object as () => formDataType,
},
});
我们点击编辑,编辑的弹窗需要显示当前行的数据,所以需要监听传过来的editData,将它赋值给弹窗中的form表单:
因为props是对象,要监听对象中的数据,所以在watch中使用下面的写法:
watch(
() => props.editData,
() => {
formData.value = props.editData;
}
);
只有点击编辑按钮,才会传入editData 数据,所以可以通过editData 控制弹窗的title
<el-dialog
:before-close="handleClose"
v-model="show"
:title="editData ? '编辑收支信息' : '添加收支信息'"
>
const handleAdd = () => {
show.value = true;
};
<DialogModal
:show="show"
@closeModal="show = false"
@handleUpdateProfiles="handleUpdateProfiles"
:editData="editData"
/>
getProfiles()方法就是从新获取表格的数据,用于修改或者添加操作完成后刷新数据
const handleUpdateProfiles = () => {
getProfiles();
};
const emits = defineEmits(["closeModal", "handleUpdateProfiles"]);
然后需要添加一个dialog的:before-close="handleClose"事件,在关闭弹窗的时候触发事件
也就是触发自定义的closeModal事件
const handleClose = () => {
formData.value = {}
emits("closeModal");
};
const formRules: formRulesType = {
describe: [{ required: true, message: "收支描述不能为空", trigger: "blur" }],
income: [{ required: true, message: "收入不能为空", trigger: "blur" }],
expend: [{ required: true, message: "支出不能为空", trigger: "blur" }],
cash: [{ required: true, message: "账户现金不能为空", trigger: "blur" }],
};
formRulesType类型也是由自己写的ts文件引入,贴上代码(跟上面使用过的同一文件):
export interface formRulesType {
describe: {
required: boolean;
message: string;
trigger: string;
}[];
income: {
required: boolean;
message: string;
trigger: string;
}[];
expend: {
required: boolean;
message: string;
trigger: string;
}[];
cash: {
required: boolean;
message: string;
trigger: string;
}[];
}
如果表单验证正确,我们就可以进行请求了:
表单验证的逻辑就不多说了,看重要的url部分,如果props.editData存在,url则为edit/${props.editData._id},不存在则为add。所以后面进行post请求的地址就是/api/profiles/加上url的内容。
请求完成之后调用自定义事件handleUpdateProfiles和handleUpdateProfiles。刷新表格数据和关闭弹窗
const handleSubmit = (formEl: FormInstance | undefined) => {
if (!formEl) return;
formEl.validate(async (valid: boolean) => {
if (valid) {
const url = props.editData?._id ? `edit/${props.editData._id}` : "add";
await axios.post(`/api/profiles/${url}`, formData.value);
// @ts-ignore
ElMessage.success("保存成功");
emits("handleUpdateProfiles");
emits("handleUpdateProfiles");
} else {
}
});
};
到这里我们就完成了整个Dialog弹窗组件的封装,核心就在于通过传值判断是编辑还是添加操作,再通过不同的操作完成不同api的请求。
在前端开发中创建自定义组件是必不可少的一项基本技能,理解这样的封装思想在实际开发中是很有必要的,可以提高代码重复利用性,减少代码量。
有疑问欢迎留言交流,批评指正。创作不易,如果对你有帮助 请点赞关注支持下~
后续会给大家带来更多的优质内容。感谢支持!!!
