本文介绍在Uni-app中实现从子页面返回父页面并携带参数的方法。通过onShow监听全局事件触发数据刷新,重点解决uni.$on重复监听导致的多次执行问题。推荐使用uni.$once自动移除监听器,确保逻辑正确执行。
一、前言
本文旨在解决一个常见需求:在列表页进入子页面后,若直接返回则不刷新列表;但若子页面数据发生变动,则需触发列表页刷新。以下记录具体的解决方案。
核心思路是在父页面的onShow()生命周期中监听返回携带的数据。当检测到特定标识符时,调用接口以刷新页面数据。
在实际操作中可能遇到一些细节问题,建议读者完整阅读后选择适合自身场景的方法,避免盲目复制代码。
二、实现方法
首先处理第一个页面one.vue。在onShow()方法中监听返回参数,该参数由上一级页面定义的变量“isRefresh”传递。
<template>
<view>
<navigator hover-class="none" url="/pages/two/two">跳到第二个页面</navigator>
</view>
</template>
<script>
export default {
data() {
return {
}
},
onShow() {
let that = this
uni.$on('isRefresh',function(data){
console.log('监听到事件来自返回的参数:' + data);
// TODO 下面执行刷新的方法
})
},
methods: {
}
}
</script>
<style>
</style>其次处理第二个页面two.vue。当从该页面返回one.vue时,需传递参数index:1。
<template>
<view>
<button @click="goBack">点击返回上一页</button>
</view>
</template>
<script>
export default {
data() {
return {
index:1,//返回上一页要穿的参数
}
},
methods: {
goBack() {
uni.$emit('isRefresh', this.index)
uni.navigateBack({
delta: 1
})
}
}
}
</script>
<style>
</style>三、遇到的坑
首次返回列表页面时功能正常,但第二次返回时会触发两次监听,第三次则触发三次,依此类推。查阅uni.$emit相关资料可知,这是一种全局通讯事件。自HBuilderX 2.0.0版本起,系统支持uni.$emit、uni.$on、uni.$once、uni.$off,可实现跨任意组件、页面、nvue及vue的便捷通讯。所有触发事件均为App全局级别。详见事件详情说明。
调用事件后务必记得移除监听,或直接使用uni.$once,它仅调用一次并在完成后自动移除事件监听。
四、事件详解
含义说明
1. uni.$emit(eventName,OBJECT):用于监听全局自定义事件,事件由uni.emit触发,回调函数接收事件触发时传入的参数。
其中eventName为事件名,OBJECT为触发事件时附加的参数。示例代码如下:
uni.$emit('update',{msg:'页面更新'})2. uni.$on(eventName,callback):用于监听全局自定义事件,事件由uni.$emit()触发,回调函数接收所有传入数据。其中eventName为事件名,callback为事件回调函数。示例代码如下:
uni.$on('update',function(data){
console.log('监听到事件来自 update ,携带参数 msg 为:' + data.msg);
})3. uni.$once:监听全局自定义事件,事件由uni.emit触发,但仅执行一次。在第一次触发后自动移除该监听器,无需手动移除。
4. uni.$off:用于移除全局自定义事件监听器。
因此,本案例只需使用uni.$once即可满足需求,将原有的uni.$on替换为uni.$once。
<template>
<view>
<navigator hover-class="none" url="/pages/two/two">跳到第二个页面</navigator>
</view>
</template>
<script>
export default {
data() {
return {
}
},
onShow() {
let that = this
uni.$once('isRefresh',function(data){
console.log('监听到事件来自返回的参数:' + data);
// TODO 下面执行刷新的方法
})
},
methods: {
}
}
</script>
<style>
</style>Tips
- 若uni.$off未传入任何参数,则移除App级别的所有事件监听器;
- 若仅提供了事件名(eventName),则移除该事件名对应的所有监听器;
- 若同时提供了事件与回调,则仅移除该特定事件回调的监听器;
- 提供的回调必须与$on中的回调为同一引用,才能成功移除该回调监听器;
示例:
<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>至此,关于Uni-app返回上一页并携带参数的介绍完毕。如需了解更多Uni-app返回上一页携带参数的相关内容,请搜索本站历史文章或继续浏览后续文章,感谢支持!