记录:uniapp监听全局未触发事件自动退出

547 阅读1分钟

1.问题来源

最近要做一个学校的班牌项目,选择了uniapp开发(用来用去感觉真的不好用),安卓端,时间也就花在这上面了,然后需要在学生未操作系统一分钟则自动退出,但是uniapp又没有对应可以用的组件,所以只能自己来封装了。

2.解决过程

因为目前是应届毕业生,经验来说不是那么充足,所以解决一些问题还是很吃力的,前期只能在网上找类似的案例来提取自己需要的东西,不过所幸,还是找到了一个有用的案例。最后再根据自己的需求改进了一下。

2.1 getCurrentPages

uniqpp在getCurrentPages内置了一个方法$getAppWebview(),可以得到当前webview的对象实例,从而实现对 webview 更强大的控制。(此方法好像只有在app端才有用)此方法仅 App-Vue 支持

2.2 pinia

uniapp项目目前用的是vue3开发的,所以用的也是和vue3配套的pinia,再加上uview目前也出了个plus版可以很好的支持vue3项目

3.代码实现

stores.js

export const useUserStore = defineStore('user', {
	state: () => {
		return {
			token:"",
			userData:{},
		};
	},
	actions: {
		 setUserName(data) {
			//自己的方法
		},
		getUserName(){
			//自己的方法
		},
		deleteUserName(){
			this.token = "",
			this.userData={}
		}
	},
});
export const useTimeStore = defineStore('time', {
	state: () => {
		//最后一次点击事件的元素
		return {lastTime:new Date().getTime()};
	},
	actions: {
		 lastTimeUpdata(lastTime) {
			this.lastTime = lastTime
		},
	
	},
});

time.js

import {useTimeStore,useUserStore} from "@/stores/index.js"
export const timeOut = () => {
	const store = useTimeStore()
	const userStore = useUserStore()
	let WebviewList = [];
	// 上一次点击时间
	let lastTime = null
	// 当前时间
	let currentTime = null
	// 超时时间【可以自己设置】
	let sys_timeout = 60 * 1000
	// 每隔多长时间检查是否超时【可以自己设置】
	let check_time = 1000
	// 计时器【此为功能实现的方法,现在为空】	
	let goOut = null
	const isTimeOut = () => {
		// 页面上一次的点击时间
		lastTime = store.lastTime
		currentTime = new Date().getTime()
		// 超时了
		
		if ((currentTime - lastTime) > sys_timeout) {
			return true;
		} else {
			if( (currentTime - lastTime) < 30000 && (currentTime - lastTime)>29000){
				uni.showToast({
					title:"30秒内未操作将自动退出",
					duration:5000,
					position:'center'
				})
			}
			return false;
		}
	}
        //我这里写的是判断是否登录,如果登录则监听全局事件
	const isLogin = () => {
		if (userStore.token != '') {
			clearTimeout(isLogin)
			isLoginOut();
		} else {
			setTimeout(isLogin, 1000)
			// console.log("等待登录");
		}
		
	}
	const isLoginOut = () => {
		var pages = getCurrentPages();
		var page = pages[pages.length - 1];
		var currentWebview = page?.$getAppWebview();
		
                //如果超时 则关闭定时器,退出登录,继续监听是否登录
		if (isTimeOut()) {
			// 已经超时跳转到相应界面,不需要计时了
			clearTimeout(goOut)
			userStore.deleteUserName();
			
			if (currentWebview.__uniapp_route != 'pages/index/index') {
				// 需要转到的页面【这里用你自己的跳转方法和地址】
				uni.switchTab({
					url: `/pages/index/index`,
				});
			}
			isLogin()
		} else {
			if(userStore.token == ''){
				isLogin()
				clearTimeout(goOut)
			}else{
				goOut = setTimeout(isLoginOut, check_time)
			}
			
		}
		let flag = false;
		for (let webview of WebviewList) {
			if (webview?.__uniapp_route == currentWebview?.__uniapp_route) {
				flag = true;
			}
		}
		if (!flag) {
			store.lastTimeUpdata(new Date().getTime());
			WebviewList.push(currentWebview)
			currentWebview?.addEventListener('touchstart', function() {
				// console.log('点击了');
				store.lastTimeUpdata(new Date().getTime());
			}, false);
			currentWebview?.addEventListener('close', function() {
				// console.log('关闭了');
				for (var i = 0; i < WebviewList.length; i++) {
					if (WebviewList[i].__uniapp_route == currentWebview
						.__uniapp_route) {
						WebviewList.splice(i, 1);
					}
				}
			}, false);
		}
		
	}
	
	
	isLogin()
}

4.总结

写出来上面的代码后,我看还有很多可以优化的点,包括有几行代码写的比较多余了,但目前业务很多,我一个人是很难忙的过来的,所以代码也就没有优化,能跑起来就很不错了。主要是自己来记录一下思路,保证以后遇到类似的问题可以参考。