2026/4/16 22:48:39
网站建设
项目流程
佛山网站建设团队,企业网页设计价格,深圳公司排名榜,下载了网站源码Vue 组件解耦实践#xff1a;用回调函数模式替代枚举类型传递
前言
在 Vue 组件开发中#xff0c;父子组件通信是一个常见场景。当子组件需要触发父组件的某个操作#xff0c;而父组件又需要根据触发来源执行不同逻辑时#xff0c;很容易写出耦合度较高的代码。本文通过一个…Vue 组件解耦实践用回调函数模式替代枚举类型传递前言在 Vue 组件开发中父子组件通信是一个常见场景。当子组件需要触发父组件的某个操作而父组件又需要根据触发来源执行不同逻辑时很容易写出耦合度较高的代码。本文通过一个真实的登录模块重构案例介绍如何使用回调函数模式来解耦组件。问题场景业务背景在登录页面中验证码登录组件有两个操作入口点击获取验证码按钮点击登录按钮两个操作都需要检查用户是否同意服务协议。如果未同意需要弹出协议确认弹窗。用户确认后根据触发来源执行不同的后续操作。原有实现// codeLogin.enum.ts - 子组件定义枚举exportconstCodeLoginEnum{CODE_BTN:code-btn,// 获取验证码按钮LOGIN_BTN:login-btn// 登录按钮}asconst;// codeLogin.vue - 子组件constgetCode(){if(!isAgree.value){emit(changeCodeAgreeDisplayType,CodeLoginEnum.CODE_BTN);// 告诉父组件是哪个按钮emit(toggleAgreeDialog,true);return;}// ...}// login.vue - 父组件consthandleAgreementConfirm(){if(codeAgreeDisplayType.valueCodeLoginEnum.LOGIN_BTN){// 登录按钮触发的需要校验验证码if(!verifyKey.value){ElMessage.warning(请先获取验证码);return;}}codeLoginInstance.value?.doGetCode();}问题分析父组件依赖子组件内部细节父组件需要导入并理解CodeLoginEnum违反开闭原则子组件新增按钮时父组件也需要修改职责不清子组件的业务逻辑分散在父子两个组件中可测试性差父组件的逻辑依赖子组件的枚举定义解决方案回调函数模式核心思想子组件不告诉父组件我是谁而是告诉父组件确认后请通知我将后续要执行的操作封装为回调函数保存在子组件内部。父组件只需要在适当时机通知子组件执行即可。重构后的实现// codeLogin.vue - 子组件typePendingCallback(()void)|null;constpendingCallbackrefPendingCallback(null);constgetCode(){if(!isAgree.value){// 保存回调协议确认后执行获取验证码pendingCallback.value(){executeGetCode();};emit(toggleAgreeDialog,true);return;}executeGetCode();}constcodeLogin(){if(!isAgree.value){// 保存回调协议确认后执行登录pendingCallback.value(){emit(codeLogin,mobileValue.value,areaCodeValue.value,verifyCodeArg.value);};emit(toggleAgreeDialog,true);return;}emit(codeLogin,mobileValue.value,areaCodeValue.value,verifyCodeArg.value);}// 供父组件调用constonAgreementConfirmed(){pendingCallback.value?.();pendingCallback.valuenull;}defineExpose({onAgreementConfirmed});// login.vue - 父组件consthandleAgreementConfirm(){toggleIsAgree(true);toggleAgreeDialog(false);if(isAccount()){doLoginFn(loginTempData);}else{// 简单通知子组件执行回调无需知道具体是什么操作codeLoginInstance.value?.onAgreementConfirmed();}}数据流对比重构前┌─────────┐ 发送按钮类型 ┌─────────┐ 根据类型判断 ┌─────────┐ │ 子组件 │ ─────────────→ │ 父组件 │ ─────────────→ │ 子组件 │ └─────────┘ └─────────┘ └─────────┘重构后┌─────────┐ 保存回调 ┌─────────┐ 通知执行 ┌─────────┐ │ 子组件 │ ─────────────→ │ 父组件 │ ─────────────→ │ 子组件 │ └─────────┘ 请求显示弹窗 └─────────┘ onConfirmed └─────────┘ (不传类型) (不传参数)方案对比维度枚举类型传递回调函数模式耦合度高父组件依赖子组件枚举低父组件只调用方法扩展性差新增类型需改两处好只改子组件职责划分模糊逻辑分散清晰子组件自治代码量需要枚举文件无额外文件可测试性差依赖外部枚举好逻辑内聚适用场景回调函数模式适用于以下场景异步确认流程如本文的协议确认、二次确认弹窗等多入口单出口多个触发点但后续处理由同一个组件负责子组件业务自治子组件的业务逻辑不应该泄露给父组件注意事项回调清理执行完回调后记得置空避免重复执行错误处理回调执行可能失败需要考虑异常情况状态同步确保回调执行时相关状态如isAgree已更新总结组件解耦的核心原则是让每个组件只关心自己的职责。当发现父组件需要了解子组件的内部实现细节时就是重构的信号。回调函数模式是一种简单有效的解耦手段它将做什么的决策权留给子组件父组件只负责何时做的协调。这种控制反转的思想在很多设计模式中都有体现值得在日常开发中灵活运用。