
在 vue.js 中,子组件无法直接通过 props 调用父组件方法;正确做法是子组件通过 `this.$emit()` 触发自定义事件,父组件用 `@event-name` 监听并执行对应方法。
在 Vue 组件开发中,一个常见误区是试图将父组件的方法作为普通 prop 传递给子组件并直接调用(如 this.cancelOrderFunction()),这会导致 “xxx is not a function” 错误。根本原因在于:props 是单向数据流,仅用于向下传递数据或配置,不支持反向执行函数逻辑。Vue 官方推荐的、符合响应式设计原则的解决方案是使用自定义事件机制(Event Emitting)。
✅ 正确实现步骤
1. 父组件(changeStatus.vue):监听事件并定义处理逻辑
当前状态:{{ currentStatus }}
? 注意命名规范:使用 kebab-case(短横线分隔)定义事件名(如 cancel-order),在模板中以 @cancel-order 监听,符合 Vue 惯例且兼容 HTML 特性解析。
2. 子组件(cancelOrder.vue):声明 emit 并触发事件
确认取消订单? 取消 Confirm Cancel
✅ 关键点说明:
- emits: ['cancel-order'] 是 Vue 3 的显式事件声明语法(Vue 2.7+ 也支持),提升类型安全与 IDE 提示能力;
- this.$emit('cancel-order') 是标准事件触发方式,不可写作 this.cancelOrderFunction();
- 对话框关闭逻辑(dialogVisible = false)应放在 $emit 之后,确保状态同步。
⚠️ 常见错误与注意事项
- ❌ 错误:在子组件 props 中声明 cancelOrderFunction 并尝试调用 → 导致 is not a function;
- ❌ 错误:事件名大小写混用(如 @CancelOrder 或 @cancelOrder)→ Vue 模板中事件名始终转为小写,推荐统一用 kebab-case;
- ✅ 最佳实践:若需传递参数(如订单 ID),可在 $emit 中添加第二参数:this.$emit('cancel-order', orderId),父组件方法签名同步改为 cancelOrderFunction(orderId);
- ✅ 进阶建议:对复杂交互,可结合 v-model 实现双向绑定(如控制 dialog 显示状态),但核心方法调用仍应依赖事件机制。
通过以上方式,你不仅能彻底解决 "this.cancelOrderFunction is not a function" 报错,还能构建出清晰、解耦、可测试的父子组件通信结构。
立即学习“前端免费学习笔记(深入)”;










