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

Vue3:可以在composition组合式函数中返回组件吗?

解答

完全可以实现,有两种常用的落地方式:

方案1:组合式函数直接返回封装好的Modal组件实例

这种方式的好处是父组件不需要再写Modal的绑定逻辑,拿到返回的组件直接渲染即可。
修改后的useDeleteItem代码如下:

import { DeleteFunction, DjangoModel, JsonModel, Reffed } from "@/types/shared";
import { h, ref, Ref, unref } from "vue";
// 引入你的Modal组件
import ModalFree from "@/components/ModalFree.vue";

export default function useDeleteItem<
  Fn extends (...args: any[]) => Promise<void>,
>(
  deleteItemFunc: Fn,
  items: Ref<DjangoModel[]>,
  ...params: Reffed<Parameters<Fn>>
) {
  const deleteModalOpen = ref(false);
  // 新增:存储当前选中的待删除项
  const currentDeleteItem = ref<JsonModel | null>(null);

  const deleteRequest: DeleteFunction = (data: JsonModel) => {
    return deleteItemFunc(data, ...params.map(unref)).then(() => {
      deleteModalOpen.value = false;
      items.value = items.value.filter((item) => item.id !== data.id);
      currentDeleteItem.value = null;
    });
  };

  // 新增:打开删除弹窗的方法,供列表项点击时调用
  const openDeleteModal = (data: JsonModel) => {
    currentDeleteItem.value = data;
    deleteModalOpen.value = true;
  };

  // 封装Modal组件,内置绑定所有需要的props和事件
  const DeleteModal = h(ModalFree, {
    // 此处的prop名要和你的ModalFree实际定义对应,比如v-model绑定的属性是modelValue
    'modelValue': deleteModalOpen.value,
    'onUpdate:modelValue': (val: boolean) => deleteModalOpen.value = val,
    // 确认删除事件,和你的ModalFree抛出的确认事件名对应,比如confirm
    'onConfirm': () => currentDeleteItem.value && deleteRequest(currentDeleteItem.value)
  }, {
    // 如果需要自定义Modal的插槽内容也可以在这里写,比如标题、提示文案
    default: () => `确认要删除该条目吗?`
  })

  return {
    deleteRequest,
    deleteModalOpen,
    openDeleteModal,
    DeleteModal, // 直接返回封装好的Modal组件
  };
}

使用方式

在父组件的setup中调用后,直接把DeleteModal放到模板里渲染即可:

<template>
  <!-- 你的列表代码 -->
  <button @click="openDeleteModal(item)">删除</button>

  <!-- 直接渲染返回的Modal -->
  <component :is="DeleteModal" />
</template>

<script setup lang="ts">
import useDeleteItem from '@/composables/useDeleteItem'
// 省略其他引入

const { DeleteModal, openDeleteModal } = useDeleteItem(yourDeleteApi, itemsRef)
</script>

方案2:返回所有绑定参数,父组件自行绑定Modal(更灵活)

如果你的ModalFree需要大量自定义props、插槽,不想把这些逻辑耦合在组合式函数里,可以选择这种方案,不需要修改组合式函数的核心逻辑,只需要补充返回需要的状态即可:

// 只需要在原有返回值基础上补充currentDeleteItem和openDeleteModal即可
return {
  deleteRequest,
  deleteModalOpen,
  currentDeleteItem,
  openDeleteModal,
}

使用方式

在父组件里自己给ModalFree绑定属性:

<template>
  <button @click="openDeleteModal(item)">删除</button>
  <ModalFree
    v-model="deleteModalOpen"
    @confirm="deleteRequest(currentDeleteItem)"
  >
    确认要删除{{ currentDeleteItem?.name }}吗?
  </ModalFree>
</template>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 02:15:03