ZBLOG

import api from '@/store/api'; export default { name: 'App', data() { return { isReload: false, }; }, computed: { assetTag() { return th...

在你的 Vue.js 组件中,你已经实现了对页面刷新的检测和关闭窗口时的处理,但可能会遇到一些问题,例如在刷新页面时也执行了注销操作。这是因为你在 beforeunload 事件中进行了一些逻辑判断,而这些逻辑可能未能正确区分刷新与关闭窗口的行为。

让我们来优化一下这部分代码,以便能够更清晰地识别用户是否是在刷新页面,而不是直接关闭浏览器:

优化建议

  1. 利用 Performance API 检测页面类型:使用 performance.getEntriesByType('navigation') 来检测导航类型,进而决定如何处理 beforeunload 事件。
  2. 增强状态管理:确保每次加载后都设置好状态,并且当状态表明是刷新时,避免不必要的注销操作。

改进后的代码

以下是改进过的代码示例:

<template>
  <div id="app">
    <router-view />
  </div>
</template>

<script>
import api from '@/store/api';
export default {
  name: 'App',
  data() {
    return {
      isReload: false,
    };
  },
  computed: {
    assetTag() {
      return this.$store.getters['global/assetTag'];
    },
  },
  watch: {
    assetTag(tag) {
      if (tag) {
        document.title = `${tag} - ${this.$route.meta.title}`;
      }
    },
    $route(to) {
      document.title = to.meta.title || 'Page is missing title';
      if (this.assetTag) {
        document.title = `${this.assetTag} - ${to.meta.title}`;
      }
    },
  },
  created() {
    document.title = this.$route.meta.title || 'Page is missing title';
    
    let icoFlag = localStorage.getItem('CustomWebLogo');
    var link =
      document.querySelector("link[rel*='icon']") ||
      document.createElement('link');
    
    link.type = 'image/x-icon';
    link.rel = 'shortcut icon';
    link.href = `${icoFlag}.ico`;
    
    document.head.appendChild(link);
    
    this.$store.dispatch('authentication/twoFactorLogin').then(() => {
      this.$router.push('/');
    });
    
    // 检测页面是否为重新加载
    this.detectPageReload();
  },
  
  mounted() {
    window.addEventListener('beforeunload', this.handleBeforeUnload);
  },

  beforeDestroy() {
     window.removeEventListener('beforeunload', this.handleBeforeUnload);
   },

   methods: {
     detectPageReload() {
       const navEntries = performance.getEntriesByType('navigation');
       const isReload =
         navEntries.length > 0 && navEntries[0].type === 'reload';

       // 如果是刷新,则设置标记
       if (isReload) {
         sessionStorage.setItem('isPageReload', 'true');

         // 短暂延迟后清除标记,防止关闭误判
         setTimeout(() => sessionStorage.removeItem('isPageReload'), 50);
       }
     },

     handleBeforeUnload(event) {       
       const isReload = sessionStorage.getItem('isPageReload');

       // 强制触发浏览器默认弹窗
       event.preventDefault();
       event.returnValue = '';

       if (!isReload) { 
          // 执行关闭窗口时的退出操作
          this.logoutUser();
        } else { 
          // 清除标记,表示该次 unload 是由于刷新引起的,不做任何操作
          sessionStorage.removeItem('isPageReload');
        }
     },

     logoutUser() { 
       api.post('/logout', { data: [] });
       sessionStorage.removeItem('TOKEN');
       localStorage.removeItem('storedUsername');
     },
   },
};
</script>

<style lang="scss">
@import '@/assets/styles/_obmc-custom';
</style>

修改要点:

  1. 状态管理:确保在 detectPageReload() 中准确设置和清除刷新标记。
  2. 事件处理:在 handleBeforeUnload() 中,如果检测到是重载(即页面刷新的情况),则只需清除标记并返回,不执行注销操作。
  3. 不必要的监听器:移除了对 load 的监听,因为你的需求主要集中在监听页面卸载。

这样一来,当用户尝试离开页面时,通过设定好的机制,你可以更准确地判断他们是在进行何种操作,从而作出相应的响应。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=22893

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?