Uni-app返回上一页携带参数的实现与全局事件监听陷阱

作者:窗边听雨

时间:2026-10-30

浏览:220

本文介绍在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返回上一页携带参数的相关内容,请搜索本站历史文章或继续浏览后续文章,感谢支持!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章