You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3点击父组件按钮无法更新子组件ref值的问题

解决方案

你可以通过以下两种简洁的方式实现需求,避免使用prop导致的页面加载即打开模态框问题:

方法一:作用域插槽传递触发方法(推荐)

子组件通过作用域插槽向父组件暴露修改modalType的方法,父组件在插槽内直接调用该方法:

子组件 CreateReportButton

<script setup>
const modalType = ref(null);
</script>

<template>
  <!-- 向插槽传递触发方法 -->
  <slot :openPrefilledModal="() => modalType = 'prefilled'">
    <Dropdown align="right" width="64">
      <template #trigger>
        <PrimaryButton type="button" size="lg">
          <font-awesome-icon icon="fa-solid fa-plus" class="-ml-0.5 mr-1.5 h-4 w-4" aria-hidden="true" />
          {{ $t('actions.create') }} {{ $tChoice('report', 1) }}
        </PrimaryButton>
      </template>
      <template #content>
        <DropdownLink as="button" v-on:click="modalType = 'prefilled'">
          <font-awesome-icon icon="fa-regular fa-file-lines" class="text-gray-400 mr-2" />
          {{ $t('report.format.prefilled') }}
        </DropdownLink>
        <DropdownLink as="button" v-on:click="modalType = 'blank'">
          <font-awesome-icon icon="fa-regular fa-file" class="text-gray-400 mr-2" />
          {{ $t('report.format.blank') }}
        </DropdownLink>
        <DropdownLink as="button" v-on:click="modalType = 'master'">
          <font-awesome-icon icon="fa-regular fa-file-certificate" class="text-gray-400 mr-2" />
          {{ $t('report.format.from_master') }}
        </DropdownLink>
      </template>
    </Dropdown>
  </slot>

  <FormModal :show="modalType !== null" ... />
</template>

父组件 Index

<template>
  <CreateReportButton>
    <!-- 通过v-slot接收子组件传递的方法 -->
    <template v-slot="{ openPrefilledModal }">
      <PrimaryButton as="icon" size="xs" color="white" @click="openPrefilledModal">
        <font-awesome-icon icon="fa-regular fa-file-plus" class="h-4 w-4 text-gray-500" />
      </PrimaryButton>
    </template>
  </CreateReportButton>
</template>

方法二:子组件暴露方法,父组件通过ref调用

子组件通过defineExpose暴露修改modalType的方法,父组件用ref获取子组件实例后调用该方法:

子组件 CreateReportButton

<script setup>
const modalType = ref(null);

// 定义触发方法
const openPrefilledModal = () => {
  modalType.value = 'prefilled';
};

// 暴露方法给父组件
defineExpose({
  openPrefilledModal
});
</script>

<template>
  <slot>
    <!-- 原下拉内容保持不变 -->
    <Dropdown align="right" width="64">...</Dropdown>
  </slot>

  <FormModal :show="modalType !== null" ... />
</template>

父组件 Index

<template>
  <CreateReportButton ref="createReportBtnRef">
    <PrimaryButton as="icon" size="xs" color="white" @click="handleOpenModal">
      <font-awesome-icon icon="fa-regular fa-file-plus" class="h-4 w-4 text-gray-500" />
    </PrimaryButton>
  </CreateReportButton>
</template>

<script setup>
import { ref } from 'vue';

const createReportBtnRef = ref(null);

const handleOpenModal = () => {
  // 调用子组件暴露的方法
  createReportBtnRef.value?.openPrefilledModal();
};
</script>

内容的提问来源于stack exchange,提问作者ambitiouskeep

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 13:55:19