在app.vue里,监听unload事件,利用sessionStorage和localStorage存储每个网页的唯一id来实现。
unload事件触发条件
1、用户导航到另一个页面。
2、用户关闭包含该页面的标签或窗口。
3、浏览器关闭。
4、页面被重新加载(刷新)。
一开始走了弯路,想着判断是刷新还是关闭网页,用了下面这个方法判断。结果是无法准确判断的,刷新和关闭都会返回1。window.performance.navigation.type 返回的值可以是以下之一:
0:表示页面是通过首次加载进入的。1:表示页面是通过刷新进入的。2:表示页面是通过历史记录(如前进或后退按钮)进入的。
- 然后想了一招,每次打开网页,在sessionStorage存一个唯一id,就用到了uuid,
yarn add vue3-uuid. - 并把这个id存在localStorage里,localStorage是同源下,共通使用的。sessionStorage不是。
- 每次刷新页面、关闭窗口、通过按钮进入或者后退,都会触发unload事件。
- 都会从localStorage里删除一个当前页的pageId。同时也会重新生成一个新的id并添加到sessionStorage和localStorage里。
- localStorage里的ids长度始终和打开的网页窗口数量保持一致。
- 当关闭了所有的窗口,或者直接关闭整个浏览器。localStorage里的ids数组长度为0,则会触发自动退出登录。
import { uuid } from 'vue3-uuid';
onUnmounted(() => {
// 移除监听
window.removeEventListener('unload', close);
});
onMounted(() => {
//unload事件触发
//用户导航到另一个页面。
// 用户关闭包含该页面的标签或窗口。
// 浏览器关闭。
// 页面被重新加载(刷新)。
window.addEventListener('unload', close);
const pageId = uuid.v1();
// 页面刷新或者进入页面更新pageId,并设置到localStorage
sessionStorage.setItem('pageId', pageId);
if (localStorage.getItem('pageIds')) {
const ids = JSON.parse(localStorage.getItem('pageIds') as string);
ids.push(pageId);
localStorage.setItem('pageIds', JSON.stringify(ids));
} else {
localStorage.setItem('pageIds', JSON.stringify([pageId]));
}
});
//所有页面关闭就自动退出登录;
const close = () => {
const pageId = sessionStorage.getItem('pageId');
const pageIds = JSON.parse(localStorage.getItem('pageIds') || '[]');
const newPageIds = pageIds.filter((item: string) => item !== pageId);
localStorage.setItem('pageIds', JSON.stringify(newPageIds));
if (newPageIds.length === 0) {
userStore.logout(true);
}
};