t6s前端架构-bus总线事件
bus事件总线
顾名思义,就是事件(函数的)公交车,对于vue组件开发,有什么好处呢
其实就是方便组件之间通信,用js的一等公民函数
比如,2个组件
1、接口树列表(包含接口分组,接口数据)
//接口树组件 js //注册事件,当脚本变化更新(非空)接口脚本字段 bus.$on(bus.msg.onSaveLinkScript,()=>{ const {id,script} = vars.link script && api.saveLink({id, script}) }) ... //执行事件 bus.$emit(bus.msg.initLinkScript,node.script)
2、脚本编辑(依赖接口数据,随之变化,反之脚本更新需要更新接口数据)
//脚本编辑器 js //注册事件,初始化脚本编辑器内容 bus.$on(bus.msg.initLinkScript,(script)=>{ editorInstance?.setValue(script || "return 'welcome t6s'") }) ... //执行事件,脚本更新,立即更新接口 editorInstance.onDidChangeModelContent(() => { bus.$emit(bus.msg.onChangeEditLinkScript,editorInstance.getValue()) doValidate() })
用事件驱动比,对象数据传递的好处,我感觉不会污染数据
数据都是本组件内部变量,不会在其他地方改变,
即便被修改,也是定义在组件内部的bus事件,有理有据,架构清晰
bus架构,简化版本
bus.js我的设计很简单,重在高效,不需要的功能,剔除
比如,我主要解决组件之间通信,bus就是函数集合,所有只需要注册,用的时候调用即可
那么,就不需要注销,注销没有意义,一旦注册,就是必须要使用的
先看一下,理解一下,bus.js
const fns = {} const $on = (name,fn)=>{//相同消息,事件函数字符串,注意别重复 fns[name] = fns[name] || [] fns[name] = fns[name].filter(it => it.toString() !== fn.toString()) //通过脚本字符串对比,过滤过期事件 fns[name].push(fn) } const $emit = function (name){ fns[name]?.forEach( (fn)=>{ fn.apply(this,Array.from(arguments).slice(1)) }) } export default { $on, $emit, msg:{ loadCaseList:'加载用例列表', updateFlowCount:'更新用例流程数量', initLinkScript:'初始化接口脚本', onChangeEditLinkScript:'脚本编辑实时更新', updateRunLinkResult:'更新接口运行数据', onSaveLinkScript:'保存接口脚本', onRunLinkScript:'运行接口脚本' } }
精髓
看完之后,可能会有疑问,为啥同名同参数事件函数会有多个,每次emit执行也是批量
这里就是为啥定义bus,而不使用直接定义单纯单个函数(不实现,用的时候实现)
批量注册批量执行才是bus的精髓
假如,有3个组件
1、数据组件
2、曲线展示组件
3、柱状图展示组件
如果组件1,数据变化,需要更新 2和3组件,就需要再2 3组件内部定义相同事件(名称相同)实现不同(需要改变各自组件内部对应值)
当然,有人会说可以用,父组件给子组件传递值,要维护这种关系代价很大,非常影响架构设计
我的架构中,基本不用父子传递数据,和Vue3依赖注入:provide和inject(非父子关系数据传递)
管理起来非常麻烦,代码层次较为复杂,不清晰
还是要组件内部数据,自己管理好稳妥些
坑点
事件名称与函数相同事件,被判定过期事件
为何要判断过期,因为组件在挂载销毁时,变量都会重新初始化,而bus事件引用了过期变量,所以要重新注册,并且需要过滤掉过期事件函数(bus是全局的,不会随组件销毁而失效,需要手动过滤)
例子:
//两个方法都是一样的,必须把变量传递修改下,让字符串不相等,否则,只会有一个生效 //fns[name] = fns[name].filter(it => it.toString() !== fn.toString()) //过滤过期事件 //LinkArgsList.vue bus.on(bus.msg.linkEditorArgsPanelHighChange,(h)=>{ const height = h-122.2 vars.scrollHeight = height+'px' }) //LinkArgs.vue bus.on(bus.msg.linkEditorArgsPanelHighChange,(height)=>{ height = height-122.2 vars.scrollHeight = height+'px' })
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了