vue2
ref+emit
子组件
<template>
<div>
<el-dialog
title="新增"
:visible.sync="dialogFormVisible"
@close="handleClose"
>
<el-form :model="form">
<el-form-item label="姓名">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="年龄">
<el-input v-model="form.age"></el-input>
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="dialogFormVisible = false"
>确 定</el-button
>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
name: "FormPanel",
data() {
return {
dialogFormVisible: false,
form: {
name: "",
age: "",
},
};
},
methods: {
/**
* 关闭回调
*/
handleClose() {
this.$emit("handleCallback", {
id: "6886", type: 2 });
},
/**
* 打开
* @param {Object} row 父组件传来参数
*/
handleOpen(row) {
console.log("父组件传来参数", row);
this.dialogFormVisible = true;
},
},
};
</script>
父组件
<template>
<div>
<el-button type="primary" @click="handleOpenPanel">新增</el-button>
<form-panel ref="refFormPanel" @handleCallback="handleCall"></form-panel>
</div>
</template>
<script>
import FormPanel from "./components/formPanel.vue";
export default {
name: "Parent",
components: {
FormPanel },
methods: {
/**
* 弹窗关闭回调
* @param {Object} res 子组件传回参数
*/
handleCall(res) {
console.log("子组件传回参数: ", res);
},
/**
* 通过ref打开弹窗面板
*/
handleOpenPanel() {
this.$refs.refFormPanel.handleOpen({
id: "a1", type: 1 });
},
},
};
</script>
vue3
语法糖+ref+emit(一)
子组件
html
<template>
<div>
<el-dialog
v-model="isDialog"
:title="titleObj[title]"
width="50%"
append-to-body
>
<el-form :model="dialogForm" label-width="68">
<el-row :gutter="10">
<el-col :span="12">
<el-form-item label="姓名" required>
<el-input
class="w_100_"
v-model="dialogForm.name"
placeholder="请输入姓名"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="年龄">
<el-input
class="w_100_"
v-model="dialogForm.age"
placeholder="请输入年龄"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<el-row class="mt_20">
<el-col class="d_f jc_fe" :span="24">
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleSubmit">确认</el-button>
</el-col>
</el-row>
</el-dialog>
</div>
</template>
<script name="FormPanel" setup>
// 这个emit很重要
const emit = defineEmits(["handleFormCallback"]);
let info = reactive({
isDialog: false,
title: "add",
titleObj: {
add: "新增",
edit: "编辑",
},
dialogForm: {
// 名称
name: "",
// 年龄
age: ""
},
}),
{
isDialog, title, titleObj, dialogForm } = toRefs(info);
/**
* 确认(提交)
*/
async function handleSubmit() {
console.log("表单数据: ", dialogForm.value);
// 提交成功后触发父组件事件
emit("handleFormCallback", title);
}
/**
* 取消
*/
function handleCancel() {
isDialog.value = !isDialog;
}
/**
* 父组件执行
* @param {String} id 行id
* @param {String} key 标题类型
*/
async function handleOpenFormPanel(id = "", key = "add") {
title = key;
if (key === "add") {
dialogForm.value = {
// 名称
name: "",
// 年龄
age: ""
};
} else {
console.log("根据id获取详情: ", id);
}
nextTick(async () => {
isDialog.value = true;
});
}
// 暴露方法与属性(这个是重点)
// 如果不暴露,则父组件无法执行此函数
defineExpose({
handleOpenFormPanel,
});
</script>
–
父组件
<template>
<div>
<el-button type="success" @click="handleAdd('add')">新增</el-button>
<el-button type="primary" @click="handleEdit('id68', 'edit')">编辑</el-button>
<!-- 新增/编辑面板 -->
<form-panel ref="refFormPanel" @handleFormCallback="handleCallback"></form-panel>
</div>
</template>
<script name="Parent" setup>
import FormPanel from "./components/formPanel.vue";
const refFormPanel = ref(null);
/**
* 新增
* @param {String} type 面板标题类型
*/
function handleAdd(type) {
refFormPanel.value.handleOpenFormPanel("", type);
}
/**
* 编辑
* @param {String} id 行id
* @param {String} type 面板标题类型
*/
function handleEdit(id, type) {
refFormPanel.value.handleOpenFormPanel(id, type);
}
/**
* 子组件回调
*/
function handleCallback(res = "") {
console.log("子组件返回的数据: ", res);
}
</script>