Vue 3 中父子组件的交互与弹框控制:v-model 和事件传递的实践
目录
- 前言
- 1. Demo
- 2. 基本知识
前言
🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF
原先的父子组件传递已经说过很多知识,推荐阅读
- 详细分析Vue3中的props用法(父传子)
- 详细分析Vue3中的defineExpose(附Demo)
- 详细分析Vue3中的emit用法(子传父)
以下为实战中抽离的Demo,主要讲解一些基本事项!
1. Demo
先以实战中抽离的Demo为示例进行讲解:
父组件:ParentComponent.vue
<template>
<div>
<!-- 弹框触发按钮 -->
<el-button
link
type="info"
@click="openDialog(scope.row.id)"
>
打开弹框
</el-button>
<!-- 弹框组件 -->
<ChildDialog v-model:modelValue="isDialogVisible" @confirm="handleConfirm" />
</div>
</template>
<script setup>
import { ref } from 'vue';
import ChildDialog from './ChildDialog.vue';
const isDialogVisible = ref(false);
const currentId = ref(null);
const openDialog = (id) => {
currentId.value = id; // 传递当前行的 ID
isDialogVisible.value = true; // 打开弹框
};
const handleConfirm = (data) => {
console.log('弹框确认:', data);
// 可以在这里处理业务逻辑,例如提交请求
};
</script>
子组件:ChildDialog.vue
<template>
<el-dialog :model-value="modelValue" @update:model-value="updateVisible" title="选择操作" width="30%">
<el-radio-group v-model="selectedOption">
<el-radio :label="1">选项一</el-radio>
<el-radio :label="0">选项二</el-radio>
</el-radio-group>
<template #footer>
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleConfirm">确定</el-button>
</template>
</el-dialog>
</template>
<script setup>
import { ref, watch } from 'vue';
const props = defineProps({
modelValue: {
type: Boolean,
required: true
}
});
const emit = defineEmits(['confirm', 'update:modelValue']);
const selectedOption = ref(1); // 默认选中第一个选项
const handleConfirm = () => {
emit('confirm', { selected: selectedOption.value });
emit('update:modelValue', false); // 关闭弹框
};
const handleCancel = () => {
emit('update:modelValue', false); // 关闭弹框
};
const updateVisible = (value) => {
emit('update:modelValue', value); // 更新弹框的显示状态
};
watch(() => props.modelValue, (newVal) => {
if (!newVal) {
selectedOption.value = 1; // 重置选项
}
});
</script>
总的来说:
-
父组件:
使用 v-model:modelValue 来控制子组件的弹框显示和隐藏
当点击按钮时,调用 openDialog 打开子组件弹框
子组件通过 @confirm 传递数据,并在父组件中处理逻辑 -
子组件:
使用 v-model 来接收父组件传递的 modelValue,并通过 update:modelValue 事件更新父组件的状态
提供了选择框供用户选择,点击确认按钮时,将选中的数据通过 emit 传递给父组件
2. 基本知识
通过上述的Demo,基本知识如下:
- 父组件(index 页面):
父组件的功能是展示一个按钮并控制弹框的显示与隐藏
父组件通过 v-if 和 v-hasPermi 进行条件渲染和权限验证,并且当按钮被点击时,会调用 openLimitDialog 函数,展示子组件弹框
-
v-model 双向绑定:
父组件通过v-model:modelValue="isLimitDialogVisible"
控制 LimitApproval 弹框的显示与隐藏
v-model 本质上是对 modelValue 的双向绑定,在父组件中直接控制子组件的 modelValue 属性来控制弹框的可见性 -
事件传递: 父组件通过
@confirm="handleLimit"
接收子组件的 confirm 事件,触发 handleLimit 方法来处理确认操作 -
动态参数传递: 父组件通过
openLimitDialog(scope.row.id)
将当前行的 id 传递给子组件,并存储在 currentLimitId 中
这是通过事件参数传递的方式,使得子组件能够获得需要操作的具体数据
- 子组件(LimitApproval.vue):
子组件展示了一个 el-dialog,并通过 el-radio-group 来展示限量和不限量的选择框
当用户点击确定按钮时,子组件通过 emit 向父组件发送 confirm 事件,同时传递选中的数据
-
v-model 传递数据:
子组件通过 v-model 绑定 modelValue,确保当父组件修改这个属性时,子组件能够实时响应并更新显示
update:modelValue 事件用于同步父子组件间的显示状态 -
事件传递与父组件交互:
当用户点击确定按钮时,子组件会通过 emit 触发 confirm 事件,将用户的选择(selectedResult)传递给父组件
父组件通过@confirm="handleLimit"
捕获并处理这个事件,执行对应的逻辑 -
状态管理:
selectedResult 存储了用户的选择状态,并在点击确认时通过事件传递给父组件
在 watch 中监听 modelValue 的变化,用于重置 selectedResult 的值