乐趣区

关于前端:如何实现多-Tab-同步登陆和退出

一. 场景再现

  1. 前两天接到一个需要,要求实现相似于 B 站 的那种,当我同时关上多个 Tab 标签的时候,如果我在某一个窗口退出了,那么其它窗口的登陆状态也须要同步退出。如下图,我同时关上了两个 tab
  2. 当我点击其中一个窗口的退出时,你会发现另外一个窗口也神奇的同步退出了。
  3. 通过查阅相干材料,比较简单的办法有两种,一个是 window.postMessage,另外一个就是监听 localStorage 的变动,接下来我会别离演示这两种计划。

二. 搭建一下根底款式

  1. 留神:款式方面,在这里我应用的是 UnoCSS,将款式內联在了标签里,如果你还不理解这种写法,你能够点击下方的文章学习。不过即便你之前从未理解过 UnoCSS,也不会影响你上面的浏览,因为款式不是本文的重点,并不影响整体浏览。
    🫱手把手教你如何创立一个代码仓库
  2. 如果恰好你应用了 Unocss 那么你能够间接复制我上面的代码疾速开始明天的常识。

    <script setup lang="ts">
    import {ref} from "vue";
    
    const isLogin = ref<boolean>(true);
    </script>
    
    <template>
      <div class="w-100vw h-100vh text-14px text-black">
    <div
          class="w-full h-full flex items-center justify-center flex flex-col gap-10px"
    >
          <span>{{isLogin ? "已登陆" : "已登记"}}</span>
          <button class="mr-10px" @click=""> 关上新窗口 </button>
      <button @click=""> 退出 </button>
    </div>
      </div>
    </template>
    
  3. 如果你没有用到 Unocss,你也不必放心,因为咱们的款式非常简单,页面只有三个元素。一个示意是否曾经 登陆 的文案,而后剩下两个按钮,一个是关上新窗口的性能,一个是退出登陆的性能。

三. window.postMessage

  1. 咱们疾速书写一个关上新窗口的函数。
  2. 此时咱们还需在以后页面挂载当前给 window 绑定一个事件来搭配 window.open 之后咱们要做的事件。这里咱们给 window 绑定了一个监听事件,事件的名称叫做 “message”,回调函数中的参数 e 咱们临时不须要关系,咱们持续往下进行代码书写。

    能够看到咱们的 window.open 正确的关上了一个新的 tab

  3. 接下来咱们编写咱们的 退出按钮 的函数。

    首先很简略,它把咱们的 isLogin 变量标记为 false,咱们就能够通过观察 span 标签中的文案变动察看咱们的状态。

    另外一个重点,这里咱们用到了 window.opener 这个属性,这个属性代表着它上一级的窗口。咱们要向谁产生音讯?上一级窗口对吧?调用 target?.postMessage 函数,这个函数第一个参数就是咱们要发送的音讯。咱们就用 “退出” 字符串当作咱们退出的信号吧。第二个参数是咱们用 / 示意默认为以后的 origin。届时上一级窗口的回调函数的事件对象就会收到咱们的音讯。

  4. 试验一下,能够很分明的看到,咱们第一个父窗口曾经收到了来自子窗口的音讯 “退出”,它是事件对象的 data属性的值。

    那么此时咱们就能够判断,如果收到了退出的信号,那么我也跟着把 isLogin 变量的值改为 false,也实现退出的动作。

  5. 测试一下成果:

四. 监听 localStorage

  1. 对于 storage 事件,这外面有一个误区,心愿读者不要被误导,这个事件无奈监听 sessionStorage 的变动。在 MDN 的中文文档中,并没有特地显著指出这一点。

    而在英文文档中明确指出了这个非常要害的信息。

    晓得了这个关键点,就晓得为什么我要写明要应用 localStorage 了。

    原文地址:MDN Storage Event

  2. 其实这个事件的用法和下面的 “message 事件” 十分相似。第一步,你只需把咱们给 window 绑定的事件替换为 “storage” 即可。
  3. 而后批改咱们的 logOut 函数。在执行的时候在 localStorage 里写入一个 isLoginfalse 的状态。(storage 只能写入字符串类型的值,所以须要 JSON 序列化一下,基础知识不过多赘述。)
  4. 能够看到,咱们第二个 tab 退出的时候,第一个 tab 曾经监听到了 storage 的变动了。

    咱们看一下这个事件对象身上的信息,这外面有两个属性是咱们须要的。一个是 key,也就是发生变化的值,另外一个是 newValue 代表咱们刚刚设置的值。

  5. 晓得了这些信息,咱们就能够在事件的回调函数中做一些解决。
  6. 测试一下:

五. 总结

实现办法其实还挺简略的,在理论工作中,咱们我的项目的实现就是将 token 寄存到 localStorage 里,通过监听 token 的存在来实现多 tab 的同时退出和同时登陆。

其实还有别的办法,比方同时开启一个 webSocket,让后端搭配同步向 tab 发消息等。

退出移动版