<!-- 用户新增和修改组件 -->
<template><!-- 弹窗 --><el-dialog v-model="visible" :title="title" width="60%" @close="handleClose"><el-form ref="dataFormRef" :model="formData" :rules="rules" label-width="80px"> ......</el-form><template #footer><div class="dialog-footer"><el-button type="primary" :loading="loading" @click="handleSubmit">确 定</el-button><el-button @click="handleClose">取 消</el-button></div></template></el-dialog>
</template><script setup>
import {ref, reactive, watch, nextTick} from 'vue'
import { ElMessage } from 'element-plus'// 1.使用 Vue 3.4+ 的 defineModel 定义了一个名为 visible 的双向绑定变量。父组件通过 v-model 传入该值,子组件修改它会自动同步到父组件,常用于控制弹窗显示/隐藏
const visible = defineModel({type: Boolean,default: false
})// 定义属性
const props = defineProps({// 弹窗类型 add: 新增 edit: 修改title: {type: String,default: ''},// 表单数据initData: {type: Object,default: () => ({})}
})// 2.定义事件
const emit = defineEmits(['success'])const loading = ref(false)
const dataFormRef = ref()// 本地表单数据(用于双向绑定和验证)
const formData = reactive({});// 表单校验
const rules = {......
};
// 监听外部传入的显示状态,当 visible 为 true 时填充表单数据
watch(visible, (val) => {if (val) {// 打开时填充表单数据nextTick(() => {Object.assign(formData, props.initData || {})dataFormRef.value.clearValidate()})}
})// 关闭弹窗
const handleClose = () => {visible.value = false
}// 提交表单
const handleSubmit = () => {dataFormRef.value.validate(async (valid) => {if (valid) {try {loading.value = true;const submitData = {...formData}// 新增或修改if (submitData.userId) {await UserAPI.update(submitData)ElMessage.success("修改成功");} else {await UserAPI.add(submitData)ElMessage.success("新增成功");}// 3.通知父组件刷新列表emit('success') handleClose();} catch (error) {ElMessage.error(error?.message || '操作失败');} finally {loading.value = false;}}});
}
</script><style lang="scss" scoped></style>
父组件 index.vue
<template><div class="app-container-row"><el-button type="success" icon="plus" @click="handleAddOrUpdate(undefined)">新增</el-button><!-- 1.子组件 v-model="dialog.visible" 对应子组件的 const visible = defineModel({type: Boolean, default: false})@success="handleQuery" 对应子组件的 const emit = defineEmits(['success']); emit('success') --><UserFormDialogv-model="dialog.visible":title="dialog.title":init-data="initFormData"@success="handleQuery"/></div>
</template><script setup>
import {onMounted, reactive, ref, toRaw} from 'vue'
import UserFormDialog from "@/views/system/user/UserFormDialog.vue";/*** 定义组件名称:在调试工具(如 Vue DevTools)中会显示为组件名称,便于识别和调试* 支持<keep-alive>缓存*/
defineOptions({name: 'User'
})//==============用户表单=================
// 2.初始化子组件标题和显隐
const dialog = reactive({title: "",visible: false,
});const defaultFormData = {userId: undefined,loginName: '',nickName: '',gender: 1,deptId: undefined,phone: '',email: '',remark: ''
}const initFormData = reactive({ ...defaultFormData })// 新增或修改页面
function handleAddOrUpdate(rowData) {......dialog.visible = true;
}// 查询
function handleQuery() {}
</script><style lang="scss" scoped></style>