npm package: @miapp/emitter
Description: 事件触发器
Author: huya.nzb
Latest version: 1.0.1

# emitter

![](https://img.shields.io/npm/v/@miapp/emitter.svg?style=flat) ![](https://img.shields.io/npm/dt/@miapp/emitter.svg?style=flat)

> 事件触发器

## 使用

### 直接使用

```js
import Emitter from '@miapp/emitter';
const emitter = new Emitter();

// 绑定事件
emitter.on('select', callback); // 字符串
emitter.on(['select', 'confirm'], callback); // 数组
emitter.on({ // 对象
  'select': selectCallback, 
  'confirm': confirmCallback
});

// 单次绑定，API 同 on
emitter.once('select', callback);

// 触发事件
emitter.emit('select', { value });

// 解除绑定
emitter.off('select', callback); // 解除单个
emitter.off('select'); // 解除整个类型
emitter.off(); // 解除所有

// 销毁
emitter.destroy();
```

### 应用/页面/组件内使用

推荐用 `mixinEmitter`，见下文

```js
import Emitter from "@miapp/emitter";

// component.js
Component({
  didMount() {
    this.emitter = new Emitter(this);
    this.emitter.on('select', (e) => {
      console.log(e.src);
    });
  },
  didUnmout() {
    this.emitter.destroy();
  },
  methods: {
    handleTap(e) {
      this.emit('select', {
        src: 'component'
      });
    }
  }
});

// page.js
Page({
  onLoad() {
    this.emitter = new Emitter(this);
  },
  onUnload() {
    this.emitter.destroy();
  }
});

// app.js
App({
  onLaunch() {
    this.emitter = new Emitter(this);
  }
});
```

温馨提示：

* 建议命名为 `this.emitter`，内部会有一些相关处理逻辑
* 为了保证通信功能，记得初始化时传入 `this` 哦
* 页面/组件销毁时记得执行 `destroy` 方法

#### `mixEmitter`

为了解决以上几个问题，更方便的使用方式是，直接扩充应用/页面/组件的方法

```js
import { mixinEmitter } from "@miapp/emitter";

Component(mixinEmitter({
  didMount() {
    this.on('select', () => {});
  },
  methods: {
    handleTap(e) {
      this.emit('select', {
        src: 'component'
      });
    }
  }
}));

// page.js
Page(mixinEmitter({
  onLoad() {
    this.on('select', () => {});
  }
}));

// app.js
App(mixinEmitter({
  onLaunch() {
    this.on('select', () => {});
  }
}));
```

### 通信功能

#### 冒泡

冒泡至页面

```js
// component.js
// component => page
this.emit('selected|page', {
  src: 'component'
});

// page.js
this.on('selected', (e) => {
  console.log(e.src); // component
});
```

同时冒泡到页面和应用

```js
// component.js
// component => page => app
this.emit('selected|app', {
  src: 'component'
});

// page.js
this.on('selected', (e) => {
  console.log(e.src); // component
});

// app.js
this.on('selected', (e) => {
  console.log(e.src); // component
});
```

#### 捕获

如果组件想捕获页面或者全局应用发出的事件

```js
// app.js
this.emit('selected', {
  src: 'app'
});

// page.js
this.emit('selected', {
  src: 'page'
});

// component.js
// 监听 page 的 selected 事件
this.on('selected|page', (e) => {
  console.log(e.src); // page
});
// 监听 app 的 selected 事件
this.on('selected|app', (e) => {
  console.log(e.src); // app
});
```

#### 组件之间通信

利用页面事件作为中转

```js
// a => page => b

// a.js
this.emit('a:selected|page', {
  src: 'a'
});

// b.js
this.on('a:selected|page', (a) => {
  console.log(e.src); // a
});
```

#### 事件命名

`prefix:event|broadcast`

* `event`: 事件名称
* `prefix`: 自定义组件前缀，用于区分来源，默认为空
* `broadcast`: 监听从页面或者应用触发的事件，或者触发事件传播至页面或应用，只有两个值，`page` 和 `app`，默认为空

## 开发

1. `yarn` 或者 `ayarn`（[阿里内网](https://web.npm.alibaba-inc.com/package/@ali/yarn)）安装依赖
2. 小程序 IDE 打开组件（[下载地址](https://opendocs.alipay.com/mini/ide/download)）

## 更多命令

* `miapp newbranch`: 新建分支
* `miapp push`: 提交代码
* `miapp prepub`: 预发（发布 beta 版本）
* `miapp publish`: 正式发布