前言

原先的父子组件传递已经说过很多知识,推荐阅读

  1. 详细分析Vue3中的props用法(父传子)
  2. 详细分析Vue3中的defineExpose(附Demo)
  3. 详细分析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 函数,展示子组件弹框
  1. v-model 双向绑定:
    父组件通过 v-model:modelValue="isLimitDialogVisible" 控制 LimitApproval 弹框的显示与隐藏
    v-model 本质上是对 modelValue 的双向绑定,在父组件中直接控制子组件的 modelValue 属性来控制弹框的可见性

  2. 事件传递: 父组件通过 @confirm="handleLimit" 接收子组件的 confirm 事件,触发 handleLimit 方法来处理确认操作

  3. 动态参数传递: 父组件通过 openLimitDialog(scope.row.id) 将当前行的 id 传递给子组件,并存储在 currentLimitId 中
    这是通过事件参数传递的方式,使得子组件能够获得需要操作的具体数据

  • 子组件(LimitApproval.vue):
    子组件展示了一个 el-dialog,并通过 el-radio-group 来展示限量和不限量的选择框
    当用户点击确定按钮时,子组件通过 emit 向父组件发送 confirm 事件,同时传递选中的数据
  1. v-model 传递数据:
    子组件通过 v-model 绑定 modelValue,确保当父组件修改这个属性时,子组件能够实时响应并更新显示
    update:modelValue 事件用于同步父子组件间的显示状态

  2. 事件传递与父组件交互:
    当用户点击确定按钮时,子组件会通过 emit 触发 confirm 事件,将用户的选择(selectedResult)传递给父组件
    父组件通过 @confirm="handleLimit" 捕获并处理这个事件,执行对应的逻辑

  3. 状态管理:
    selectedResult 存储了用户的选择状态,并在点击确认时通过事件传递给父组件
    在 watch 中监听 modelValue 的变化,用于重置 selectedResult 的值

12-27 20:44