“快应用”是九大手机厂商联合推出的一个应用生态。这篇文章我想简单评价一下“快应用”中使用的一种事件广播机制。仅代表个人看法!

“快应用”中使用的的事件广播机制是怎样的

直接放文档中的话:

框架向开发者提供了双向的事件传递:
* 向下传递:父组件触发,子组件响应;调用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 })
    }
  }
分类: 前端

发表评论

电子邮件地址不会被公开。 必填项已用*标注