Uni-app返回上一页面并携带参数

目录

一、前言

二、实现方法

三、遇到的坑

四、事件详解


一、前言

        需要实现这么一个需求:在一个列表页面,当子页面直接返回时,不刷新列表页面。但是当子页面的数据有变动时,需要刷新列表页面。本篇博客记录一下我是如何解决这个问题的。

        解决思路:在onShow()方法内监听返回数据,当是需要当前页面刷新时,在子页面设置一个标识符,当监听到这个标识符,就调用接口刷新数据。

        在使用过程中遇到了些小坑,小白建议看完全部的内容再选适合自己的方法解决,不要盲目copy代码。

二、实现方法

1、第一个页面 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>

2、第二个页面 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 ,可以方便的进行页面的通讯 ,触发的事件都是 App 全局级别的,跨任意组件,页面,nvue,vue 等。事件详情

        调用事件后要记得移除事件,或者直接使用 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>

搬砖不易,如果对你有帮助,帮忙点个小赞吧。。。

猜你喜欢

转载自blog.csdn.net/Wjhsmart/article/details/131109993