“快应用”是九大手机厂商联合推出的一个应用生态。这篇文章我想简单评价一下“快应用”中使用的一种事件广播机制。仅代表个人看法!
“快应用”中使用的的事件广播机制是怎样的
直接放文档中的话:
框架向开发者提供了双向的事件传递:
* 向下传递:父组件触发,子组件响应;调用parentVm.$broadcast()完成向下传递
* 向上传递:子组件触发,父组件响应;调用childVm.$dispath()完成向上传递提示:
* 触发时传递参数,再接收时使用evt.detail来获取参数
* 当传递结束后,可以调用evt.stop()来结束传递,否则会一直传递下去通过$on()监控自定义事件的触发
简而言之,组件可以沿着组件树向上或向下广播事件,然后在广播途中的组件可以进行事件监听。
我对这种机制的看法
初看到这种机制,差点以为穿越回了angularjs时代,它与angularjs中的事件广播机制是一致的。都9012年了,“快应用”也是8012年的框架,我搞不懂它为什么要加入这样一种机制。
我认为使用这个机制是非常难受的,想象一下下面几个场景:
1. 在一个组件中有这样一个事件监听$on('xxx')
,然后你看到它会一脸懵逼,你不知道这个事件是从它的祖先传过来的,还是从它的后代传过来的,更无法精确定位触发事件的组件。然后你挨个组件找了半天,终于把触发事件的组件找到了。
2. 父组件有多个相同的子组件,甚至这几个子组件不在同一层级上,这个子组件里面$dispatch('xxx')
,当触发事件的时候你又懵逼了,这个事件到底是谁触发的。
3. 你和你的同事把事件名字给写重了,出bug时你的懵逼程度就无法想象了。
这个机制大大增加了组件之间的耦合度,使得程序变得难以理解,难以维护。尤其是随着应用体量的增大,还有到应用的维护阶段,或者开发人员的更换,它会让你觉得这简直就是一场噩梦。
我们应该如何使用它
谨慎。
能不用就不用。
当然,并不是一定不能用的,有时使用这种机制还是很方便的,例如全局数据的更新(onUserDataLoad)。如果你一定要使用它的话,最好有详细的注释、完整的文档,你的开发小组最好规定一些使用规范及命名规则。
但是,规范是不可能被遵守的,如果它不是强制的话。所以我还是衷心希望“快应用”如果有下次大版本更新,还是把这个机制去掉的好。
与浏览器事件相比
浏览器事件的冒泡和捕获也是使用的这种事件广播机制,但是浏览器事件是有明确的定义的,触发是由用户触发的,它本身就是适合于这种机制的。
与发布订阅模式对比
如果不使用“快应用”提供的这种机制,那可以使用什么方法来实现功能呢?一种方式就是使用发布订阅模式。
你可以实现一个事件中心,虽然也有可能会导致事件的混乱,但好处是可以明确地知道应用中有哪些事件,可以方便地管理这些事件。
当然也可以直接使用像redux这样的状态管理器。我没有试过在“快应用”中使用redux,但想必是很好用的。
与观察者模式对比
另一种替代方式是观察者模式。
可以自己实现或直接使用RXjs。好处是可以明确地知道谁是数据来源(Observable)。
$emit
当然子组件向父组件传递数据最好还是使用$emit。
但是说到$emit槽点又来了。“快应用”文档中对$emit触发的事件如何注册监听描述基本是对不上实际使用方式的。而且事件监听时竟然没有事件对象的占位符,搞得我不得不这样写:
<aea @aea-click="aeaClickHandlerFactory('aaaaaa')()"></aea>
aeaClickHandlerFactory(param) {
console.log(param)
return function (data) {
prompt.showToast({ message: data })
}
}
0 条评论