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'
})

浙公网安备 33010602011771号