uniapp有全局事件,这让全局传数据方便不少,阅读本文可同时参考官方文档(其实官网的全都被我照搬过来了,官网的还没下面的详细)。
还有一篇uniapp全局传值方式总结,里面总结了各种不同的uniapp全局传值方式。
uni.$emit(eventName,OBJECT)
触发全局的自定事件。附加参数都会传给监听器回调。
属性 | 类型 | 描述 |
---|---|---|
eventName | String | 事件名 |
OBJECT | Object | 触发事件携带的附加参数 |
示例
uni.$emit('update',{msg:'页面更新'});
//或者参数部分随意设置
uni.$emit('aaa','111');
uni.$emit 跨页面传值
// pages/index/index.vue页面
<template>
<view>
<view @tap="clickView">这是index</view>
<view @tap="gotoTest">跳转到test</view>
</view>
</template>
<script>
export default {
onLoad() {
//这里可以用uni.$on/uni.$once监听拿到数据
},
onShow() {
//这里可以用uni.$on/uni.$once监听拿到数据
},
onUnload() {
//移除所有的事件监听器
uni.$off();
},
methods: {
gotoTest() {
uni.$on('on1', this.callback) //注意这里的回调方法后面没有括号
uni.$on('on2', this.callback)
// 跳转到test.vue页面再调用clickTest_emit方法不会触发下面的跳转,只会触发uni.$on/uni.$once
uni.navigateTo({
url: '/pages/test/test'
})
},
clickView() {
// 跳转到test.vue页面再调用clickTest_emit方法不会触发下面的console.log,只会触发uni.$on/uni.$once
console.log('点击了index');
//这个方法被点击调用后可以用uni.$on/uni.$once监听拿到数据
uni.$on('on2', this.callback)
},
aaa() {
//这里可以不用uni.$on/uni.$once监听拿到数据,因为这个方法没有被调用
},
callback(e) {
// 抽离出来的uni.$on回调方法
console.log(e);
}
}
}
</script>
=====================================================================================================================
// pages/test/test.vue页面
<template>
<view @tap="clickTest_emit">这是test_emit</view>
</template>
<script>
export default {
methods: {
clickTest_emit() {
console.log("点击了test_emit");
uni.$emit('on1', '111');
uni.$emit('on2', '222');
uni.$emit('on3', '333');
},
}
}
</script>
$emit 可以用于组件传值,子组件用 this.$emit 向父组件单向传递数据,详细示例可见uniapp全局传值方式总结里的vue传值方式
uni.$on(eventName,callback)
监听全局的自定义事件。事件可以由 uni.$emit 触发,回调函数会接收所有传入事件触发函数的额外参数。(需要配合 uni.$off 使用)
属性 | 类型 | 描述 |
---|---|---|
eventName | String | 事件名 |
callback | Function | 事件的回调函数 |
示例
uni.$on('update',function(data){
console.log('监听到事件来自 update ,携带参数 msg 为:' + data.msg);
})
//或者
uni.$on('aaa',(e)=>{
console.log(e);
});
各种情况看 uni.$emit 跨页面传值示例,注意所有的 uni.$on 都必须有 uni.$off 结束监听
uni.$once(eventName,callback)
监听全局的自定义事件。事件可以由 uni.$emit 触发,但是只触发一次,在第一次触发之后移除监听器。
属性 | 类型 | 描述 |
---|---|---|
eventName | String | 事件名 |
callback | Function | 事件的回调函数 |
示例
uni.$once('update',function(data){
console.log('监听到事件来自 update ,携带参数 msg 为:' + data.msg);
})
//或者
uni.$once('aaa',(e)=>{
console.log(e);
});
各种情况类似 uni.$on
uni.$off(eventName,callback)
移除全局自定义事件监听器。(一般配合 uni.$on 使用)
属性 | 类型 | 描述 |
---|---|---|
eventName | Array<String> | 事件名,多个时是数组形式 |
callback | Function | 事件的回调函数 |
Tips(下面这几句话很重要)
- 如果没有提供参数(没有eventName),则移除所有的事件监听器;
- 如果只提供了事件(只有eventName),则移除该事件所有的监听器;
- 如果同时提供了事件与回调(eventName和callback都有),则只移除这个回调的监听器;
- 提供的回调必须跟 uni.$on 的回调为同一个才能移除这个回调的监听器;
示例
uni.$off('update',function(){
//注意这里的回调方法需要和uni.$on的回调方法保持同一个
})
//或者
uni.$off(['aaa','update'],(e)=>{
//注意这里的回调方法需要和所有uni.$on的回调方法保持同一个(所有uni.$on都用同一个callback方法,看下面的示例)
});
在调用 uni.$off 时,最好根据不同的情况去移除对 uni.$on 的使用。
<template>
<view>
<view>这是index</view>
<view @tap="gotoTest">跳转到test</view>
<view @tap="cancel">取消一个监听</view>
<view @tap="cancelAll">取消多个监听</view>
</view>
</template>
<script>
export default {
methods: {
gotoTest() {
//监听一
uni.$on('on1', this.callback)
//监听二
uni.$on('on2', this.callback)
//监听三
uni.$on('on2', (e) => {
console.log(2, e);
})
console.log('跳转到test');
uni.navigateTo({
url: '/pages/test/test'
})
},
cancel() {
console.log('取消一个监听');
uni.$off('on1', this.callback);
},
cancelAll() {
console.log('取消多个监听');
// 没有提供参数,移除所有的事件监听器(移除全部监听)
// uni.$off();
// 只提供了事件,移除该事件所有的监听器(移除该事件全部监听)
// 单个:uni.$off('on2')
// 多个:uni.$off(['on1', 'on2'])
// 同时提供了事件与回调,只移除这个回调的监听器(只移除该事件的callback回调方法的监听,on1/on2事件还保留。)
// 单个:uni.$off('on2', this.callback),这会移除监听二uni.$on('on2', this.callback)里面的this.callback
// 的监听,不会对监听三uni.$on('on2', (e) => {})里面造成任何影响,下同
// 多个:uni.$off(['on1', 'on2'], this.callback)
// 提供的回调必须跟$on的回调为同一个才能移除这个回调的监听器(就是要把回调方法抽离出来【本文的做法】)
},
callback(e) {
console.log(e);
}
}
}
</script>
=====================================================================================================================
// pages/test/test.vue页面
<template>
<view @tap="clickTest_emit">这是test_emit</view>
</template>
<script>
export default {
methods: {
clickTest_emit() {
console.log("点击了test_emit");
uni.$emit('on1', '111');
uni.$emit('on2', '222');
uni.$emit('on3', '333');
},
}
}
</script>
注意
- uni.$emit、 uni.$on 、 uni.$once 、uni.$off 触发的事件都是 App 全局级别的,跨任意组件、页面、nvue、vue 等
- 使用时,注意及时销毁事件监听,比如,页面 onLoad 里边 uni.$on 注册监听,onUnload 里边 uni.$off 移除,或者一次性的事件,直接使用 uni.$once 监听