# 事件监听注册

uniapp 提供了事件的监听注册以及触发,注册的事件都是 App 全局级别的,可以很方便的跨任意组件,页面,nvue,vue 等。

# 相关注册或触发函数

# uni.$emit(eventName,OBJECT)

触发全局的自定义事件,附加参数都会传给监听器回调函数。

属性 类型 描述
eventName String 事件名
OBJECT Object 触发事件携带的附加参数

代码示例

uni.$emit('update',{msg:'页面更新'})
1

# uni.$on(eventName,callback)

监听全局的自定义事件,事件由uni.$emit触发,回调函数会接收事件触发函数的传入参数。

属性 类型 描述
eventName String 事件名
callback Function 事件的回调函数

代码示例

uni.$on('update',function(data){
  console.log('监听到事件来自 update ,携带参数 msg 为:' + data.msg);
})
1
2
3

# uni.$once(eventName,callback)

监听全局的自定义事件,事件由uni.$emit触发,但仅触发一次,在第一次触发之后移除该监听器。

属性 类型 描述
eventName String 事件名
callback Function 事件的回调函数

代码示例

uni.$once('update',function(data){
  console.log('监听到事件来自 update ,携带参数 msg 为:' + data.msg);
})
1
2
3

# uni.$off([eventName, callback])

移除全局自定义事件监听器。

属性 类型 描述
eventName Array<String> 事件名
callback Function 事件的回调函数
  • 如果uni.$off没有传入参数,则移除App级别的所有事件监听器;
  • 如果只提供了事件名(eventName),则移除该事件名对应的所有监听器;
  • 如果同时提供了事件与回调,则只移除这个事件回调的监听器;
  • 提供的回调必须跟$on的回调为同一个才能移除这个回调的监听器;

代码示例

$emit$on$off常用于跨页面、跨组件通讯,这里为了方便演示放在同一个页面

<template>
  <view class="content">
    <view class="data">
      <text>{{val}}</text>
    </view>
    <button type="primary" @click="comunicationOff">结束监听</button>
  </view>
</template>

<script>
  export default {
    data() {
      return {
        val: 0
      }
    },
    onLoad() {
      setInterval(() => {
        uni.$emit('add', {
          data: 2
        })
      }, 1000)
      uni.$on('add', this.add)
    },
    methods: {
      comunicationOff() {
        uni.$off('add', this.add)
      },
      add(e) {
        this.val += e.data
      }
    }
  }
</script>

<style>
  .content {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }

  .data {
    text-align: center;
    line-height: 40px;
    margin-top: 40px;
  }

  button {
    width: 200px;
    margin: 20px 0;
  }
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

WARNING

  • uni.$emit、 uni.$on 、 uni.$once 、uni.$off 触发的事件都是 App 全局级别的,跨任意组件,页面,nvue,vue 等
  • 使用时,注意及时销毁事件监听,比如,页面 onLoad 里边 uni.$on 注册监听,onUnload 里边 uni.$off 移除,或者一次性的事件,直接使用 uni.$once 监听
  • 注意 uni.$on 定义完成后才能接收到 uni.$emit 传递的数据

# 场景案例

我们假设一个场景,进入app,是未登陆状态,需要在我的页面点击登陆,进入登陆页面进行登陆。登陆成功之后,返回到我的页面,实时显示登陆后的用户信息。

# 监听事件

在用户中心页面 监听事件。因为事件监听是全局的,所以使用uni.$on,需要使用uni.$off移除全局的事件监听,避免重复监听。

<template>
  <view class="content">
    <navigator url="/pages/login/index" hover-class="navigator-hover">
      <button type="default">点我登录</button>
    </navigator>
    <view v-if="usnerInfo !== null">
      <view>
        用户token:{{usnerInfo.token}},用户昵称:{{usnerInfo.nickName}}
      </view>
    </view>
  </view>
</template>

<script>
  export default {
    data() {
      return {
        usnerInfo: null
      }
    },
    onLoad() {
      // 监听事件
      console.log('on login....');
      uni.$on('login', (uinfo) => {
        this.usnerInfo = uinfo;
      })
    },
    onUnload() {
      // 移除监听事件
      console.log('off login....');
      uni.$off('login');
    },
    methods: {

    }
  }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

# 触发事件

进入登陆页面,触发事件。使用uni.$emit触发事件后,对应的uni.$on就会监听到事件触发,在回调中去执行相关的逻辑。

<template>
  <view>
    <button type="default" @click="login">登录</button>
  </view>
</template>

<script>
  export default {
    data() {
      return {};
    },
    methods: {
      login() {
        // 假设用户登录成功,此时调用emit方法触发监听事件,刷新用户登录信息
        uni.$emit('login', {
          token: 'user123456',
          nickName: 'wk123',
        });
      }
    }
  }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

基本上述场景均可以实现,本质上就是一个页面通知另一个面我发生了变化,你需要处理一下。绝大部分页面的通讯都可以使用uni.$emituni.$onuni.$onceuni.$off四个事件完成。