Vue3 父组件引用子组件并控制子组件显隐及数据传递

子组件 UserFormDialog.vue

html 复制代码
<!-- 用户新增和修改组件 -->
<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

html 复制代码
<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') 
	-->
    <UserFormDialog
        v-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>
相关推荐
qq_3508972112 分钟前
trea实用工具
vue.js·uniapp
paopaokaka_luck15 分钟前
非遗文物数字化系统(AI非遗问答、ONNX图像识别、协同过滤推荐、ECharts数据分析、非遗知识浏览与互动、文创商城订单闭环、文化活动报名签到、社区交流)
前端·javascript·vue.js·人工智能·数据分析·echarts
乘风gg19 分钟前
AI Coding 提效 2 倍是真的吗?到底怎么衡量效果
前端·ai编程·claude
用户9210802628620 分钟前
从对象到原型链:理解 this、构造函数和 new
前端
猫不易25 分钟前
Webpack 与 Vite:从 Loader / Plugin 到 Rolldown 统一引擎
前端·vite
YHL37 分钟前
🎯 Danci —— 用 AI 驱动开发一个全栈英语单词学习平台
前端·后端
平头哥~38 分钟前
Day 20 _ 3D 翻卡_perspective 写错人,卡片就穿帮
前端·3d·css3·学习资料
小聪7081 小时前
elpis-core 前端 Webpack 工程化实践
前端
2601_953988071 小时前
Ricon组态实时监控 - 毫秒级数据可视化
前端·物联网·数学建模·信息可视化·架构·前端框架
V158897262011 小时前
从滴滴模式看机器人租赁:撮合型租赁平台开发源码的调度系统设计思路
linux·前端·机器人