监听和发射事件

Cocos Creator 引擎提供了 EventTarget 类,用以实现自定义事件的监听和发射,在使用之前,需要先从 'cc' 模块导入,同时需要实例化一个 EventTarget 对象。

  1. import { EventTarget } from 'cc';
  2. const eventTarget = new EventTarget();

注意:虽然 Node 对象也实现了一些 EventTarget 的接口,但是我们不再推荐继续通过 Node 对象来做自定义事件的监听和发射,因为这样子做不够高效,同时我们也希望 Node 对象只监听与 Node 相关的事件。

监听事件

监听事件可以通过 eventTarget.on() 接口来实现,方法如下:

  1. // 该事件监听每次都会触发,需要手动取消注册
  2. eventTarget.on(type, func, target?);

其中 type 为事件注册字符串,func 为执行事件监听的回调,target 为事件接收对象。如果 target 没有设置,则回调里的 this 指向的就是当前执行回调的对象。

值得一提的是,事件监听接口 on 的第三个参数 target,主要是绑定响应函数的调用者。以下两种调用方式,效果上是相同的

  1. // 使用函数绑定
  2. eventTarget.on('foo', function ( event ) {
  3. this.enabled = false;
  4. }.bind(this));
  5. // 使用第三个参数
  6. eventTarget.on('foo', (event) => {
  7. this.enabled = false;
  8. }, this);

除了使用 on 监听,我们还可以使用 once 接口。once 监听在监听函数响应后就会关闭监听事件。

取消监听事件

当我们不再关心某个事件时,我们可以使用 off 接口关闭对应的监听事件。

off 接口的使用方式有以下两种:

  1. // 取消对象身上所有注册的该类型的事件
  2. eventTarget.off(type);
  3. // 取消对象身上该类型指定回调指定目标的事件
  4. eventTarget.off(type, func, target);

需要注意的是,off 方法的参数必须和 on 方法的参数一一对应,才能完成关闭。

我们推荐的实现方式如下:

  1. import { _decorator, Component, EventTarget } from 'cc';
  2. const { ccclass } = _decorator;
  3. const eventTarget = new EventTarget();
  4. @ccclass("Example")
  5. export class Example extends Component {
  6. onEnable () {
  7. eventTarget.on('foobar', this._sayHello, this);
  8. }
  9. onDisable () {
  10. eventTarget.off('foobar', this._sayHello, this);
  11. }
  12. _sayHello () {
  13. console.log('Hello World');
  14. }
  15. }

事件发射

发射事件可以通过 eventTarget.emit() 接口来实现,方法如下:

  1. // 事件发射的时候可以指定事件参数,参数最多只支持 5 个事件参数
  2. eventTarget.emit(type, ...args);

事件参数说明

在发射事件时,我们可以在 emit 函数的第二个参数开始传递我们的事件参数。同时,在 on 注册的回调里,可以获取到对应的事件参数。

  1. import { _decorator, Component, EventTarget } from 'cc';
  2. const { ccclass } = _decorator;
  3. const eventTarget = new EventTarget();
  4. @ccclass("Example")
  5. export class Example extends Component {
  6. onLoad () {
  7. eventTarget.on('foo', (arg1, arg2, arg3) => {
  8. console.log(arg1, arg2, arg3); // print 1, 2, 3
  9. });
  10. }
  11. start () {
  12. let arg1 = 1, arg2 = 2, arg3 = 3;
  13. // At most 5 args could be emit.
  14. eventTarget.emit('foo', arg1, arg2, arg3);
  15. }
  16. }

注意:出于底层事件派发的性能考虑,这里最多只支持传递 5 个事件参数。所以在传参时需要注意控制参数的传递个数。

系统内置事件

以上是通用的事件监听和发射规则,在 Cocos Creator 中,我们默认支持了一些系统内置事件,具体的说明及使用方式请参考: