当前位置: 首页 > news >正文

Vue3中defineProps(定义onSave)与defineEmits(定义save)造成命名冲突

组件部分代码:

src\components\common\WorkflowMainDialog.vue

interface Props { /** 对话框标题 */ title?: string; /** 活动实例(包含必要信息) */ activityInstance: ActivityInstance; /** 校验数据(返回 false 或 reject 则return) */ validate?: () => boolean | Promise<boolean>; /** 保存函数(接收一个 done 回调,保存完成后调用) */ onSave?: (done: () => void) => void | Promise<void>; } const props = withDefaults(defineProps<Props>(), { title: "流程办理", validate: undefined, onSave: undefined }); const emit = defineEmits<{ /** * 已办理(办理/退回后) */ audited: []; /** * 保存(已通过 onSave 处理,此事件可作为额外通知) */ save: []; }>();

defineProps定义了onSave,defineEmits定义了save,造成命名冲突

使用组件

<WorkflowMainDialog v-if="store.currentCapitalAllocate?.activityInstance" ref="capitalAllocateWorkflowInstanceDialogRef" title="资金分配" :activity-instance="store.currentCapitalAllocate?.activityInstance" :validate="validateAllocate" :onSave="handleSaveAllocate" @audited="handleAudited">

报错如下:

不能将类型“(done: () => void) => Promise<void>”分配给类型“((done: () => void) => void | Promise<void>) & (() => any)”。 不能将类型“(done: () => void) => Promise<void>”分配给类型“() => any”。 目标签名提供的自变量太少。预期为 1 个或更多,但实际为 0 个。ts-plugin(2322) WorkflowMainDialog.vue(40, 3): 所需类型来自属性 "onSave",在此处的 "{ readonly title?: string | undefined; readonly activityInstance: ActivityInstance; readonly loading?: boolean | undefined; readonly isModified?: boolean | undefined; ... 5 more ...; readonly onAudited?: (() => any) | undefined; } & VNodeProps & AllowedComponentProps & ComponentCustomProps & Record<...>" 类型上声明该属性 通义灵码一键修复 (property) onSave?: (((done: () => void) => void | Promise<void>) & (() => any)) | undefined 保存函数(接收一个 done 回调,保存完成后调用)

您遇到的类型错误确实是由于defineEmits中声明了save事件,导致 Vue 自动生成一个同名的onSaveprop(类型为() => any),与您在defineProps中自定义的onSave(类型(done: () => void) => void | Promise<void>)合并为交叉类型,无法兼容。

即使父组件没有使用@save,类型系统仍然会认为组件可能接收这个 prop,因此冲突依然存在。

解决方案

1. 修改自定义 prop 名称(推荐)

onSave改为不与事件监听器冲突的名称,例如saveHandler

修改组件内部:

ts

interface Props { // ... /** 保存函数(接收一个 done 回调,保存完成后调用) */ saveHandler?: (done: () => void) => void | Promise<void>; // 改名 } // 使用处 const buttonSaveDisabled = computed( () => props.loading || auditLoading.value || props.saving || !props.isModified || !props.saveHandler ); const handleSaveWithDone = async (event?: MouseEvent, done?: () => void) => { if (props.saveHandler) { await props.saveHandler(() => { done?.(); emit("save"); // 可选,仍可触发 save 事件 }); } else { done?.(); } };

模板中:

vue

<BasePreventReClickButtonEmit v-if="saveHandler" class="short-btn" type="primary" plain :disabled="buttonSaveDisabled" :timeout="0" @click="handleSaveWithDone" > 保存 </BasePreventReClickButtonEmit>

父组件使用时:

vue

<WorkflowMainDialog ... :save-handler="handleSaveAllocate" @audited="handleAudited" @save="onSaveComplete" <!-- 可选 --> >

2. 如果不需要save事件,可以从defineEmits中移除

ts

const emit = defineEmits<{ audited: []; // 移除 save 事件 }>();

但保留事件有时是有用的,比如父组件想监听保存完成做额外操作。因此方案 1 更灵活。

为什么必须改名?

因为 Vue 的<script setup>会自动为defineEmits中声明的事件生成对应的 props(命名规则onXxx),类型为((...args: any[]) => any) | undefined。这些 props 会与您在defineProps中声明的同名的 prop 合并,导致 TypeScript 要求您的 prop 同时满足两种签名。

改名后,自定义 propsaveHandler与自动生成的onSave不再冲突,问题解决。

http://www.jsqmd.com/news/486834/

相关文章:

  • Wan2.1-umt5与ComfyUI工作流结合:探索文本驱动的复杂自动化流程
  • 实测AI读脸术:年龄性别识别效果展示,附详细使用教程
  • 智能翻译插件:突破语言壁垒的网页阅读解决方案
  • 基于庐山派K230开发板的手部关键点检测与手势识别实战
  • CAN总线安全新思路:为什么说VoltageIDS的电气特性检测比传统方案更靠谱?
  • 南北阁Nanbeige4.1-3B与Python开发:从环境搭建到项目实战
  • GLM-OCR与Dify平台集成:打造零代码AI工作流应用
  • 实战openspec
  • Substance Painter 磨损纹理:一键生成与细节调整
  • ACE-Step应用解析:如何将AI音乐生成集成到你的应用系统中?
  • 深入解析Arm Cortex-A715:架构特性与性能优化实践
  • 3大技术突破!ofd.js如何重塑医疗教育行业文档处理
  • DeepStack算法解析:从游戏树到神经网络实战
  • Audio Pixel Studio语音合成实战:API接口封装与Postman调试全流程
  • ChipWhisperer入门指南:从硬件连接到Jupyter Notebook实战(附常见问题解决)
  • Yi-Coder-1.5B数学能力测试:程序辅助解决奥数难题
  • 从音频原理到实战:乐鑫 esp-sr SDK 核心算法与应用场景解析
  • OAuth2.0实战:从授权码到安全集成的完整指南
  • Win11笔记本RTX3070Ti显卡实战:3D Gaussian Splatting环境配置避坑指南
  • 多语言语义对齐实验:NLP-StructBERT在中英句子相似度上的表现
  • Halcon实战:angle_lx和angle_ll算子的5个工业视觉检测应用场景
  • 暗黑破坏神2单机增强终极方案:PlugY全场景配置指南
  • combox改成下拉列表背景没法变成白色
  • 永磁同步电机的MTPA最大转矩电流比控制算法与弱磁控制仿真模型解析(附建模文档)
  • Ai8051U最小系统板:RISC-V内核8051兼容硬件迁移方案
  • 边缘检测性能评估全解析:从PR曲线到OIS/ODS的实战指南
  • ESP32-IDF最新ADC校准指南:如何用曲线拟合方案提升11dB衰减下的测量精度?
  • 网盘直链解析技术实战指南:从原理到行业应用优化方案
  • 为什么你的Dify集成总卡在审批流?揭秘头部金融客户已验证的5层流程引擎解耦方案
  • 从零到一:数组定义与NumPy操作实战闯关指南