最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS中BroadcastChannel實(shí)現(xiàn)瀏覽器標(biāo)簽頁通信

 更新時(shí)間:2025年10月21日 10:02:51   作者:Lewiis  
瀏覽器標(biāo)簽頁通信常用于列表頁進(jìn)入詳情頁所進(jìn)行的標(biāo)簽頁間通信的情況,實(shí)際使用例如博客頁面的列表和文章編輯頁面、音樂網(wǎng)站的列表和音樂播放詳情等,本文就來詳細(xì)的介紹一下BroadcastChannel實(shí)現(xiàn)瀏覽器標(biāo)簽頁通信,感興趣的可以了解一下

瀏覽器標(biāo)簽頁通信常用于列表頁進(jìn)入詳情頁所進(jìn)行的標(biāo)簽頁間通信的情況,實(shí)際使用例如博客頁面的列表和文章編輯頁面、音樂網(wǎng)站的列表和音樂播放詳情等。

window.open()實(shí)現(xiàn)

使用常用的window.open()API也可以實(shí)現(xiàn),但會(huì)存在以下問題:

  1. 打開新頁面時(shí)瀏覽器標(biāo)簽頁焦點(diǎn)也會(huì)跳轉(zhuǎn)到新頁面(如果沒有標(biāo)簽頁焦點(diǎn)不變的需求可以忽略不計(jì));
  2. 打開新頁面導(dǎo)致新頁面全局刷新(多頁應(yīng)用或跳轉(zhuǎn)的新頁面內(nèi)容較少可忽略不計(jì));

BroadcastChannel實(shí)現(xiàn)

BroadcastChannel 是 Web API 里用于在同源的不同瀏覽器上下文(像不同的窗口、標(biāo)簽頁、iframe 等)間進(jìn)行通信的機(jī)制,因此可以規(guī)避以上兩個(gè)問題:

實(shí)現(xiàn)過程

創(chuàng)建兩個(gè)路由頁面

  • 列表頁 /
  • 詳情頁/detail

列表頁

<template>
  <div class="table-box">
    <el-table :data="tableData" style="width: 100%">
      <el-table-column prop="username" label="用戶名" />
      <el-table-column prop="sex" label="性別" />
      <el-table-column fixed="right" label="操作" min-width="120">
        <template #default="scope">
          <el-button
            link
            type="primary"
            size="small"
            @click="handleClick(scope.row)"
          >
            詳情
          </el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script setup>
import { ref } from "vue";
import { userList } from "@/utils/data";
const handleClick = async (row) => {
  // channel通信
  const channel = new BroadcastChannel("user_detail");
  const tabCount = localStorage.getItem("TAB_COUNT");
  if (!tabCount || tabCount === "1") {
    await localStorage.setItem("TAB_COUNT", "2");
    await sessionStorage.setItem("TAB_ID", row.id);
    window.open("/detail", "user_detail");
  } else {
    channel.postMessage(row.id);
  }
};

const tableData = ref(userList);
</script>

詳情頁

<template>
  <el-descriptions
    class="margin-top"
    title="用戶信息表"
    :column="3"
    size="large"
    border
  >
    <template #extra>
      <el-button type="primary" @click="goBack">返回</el-button>
    </template>
    <el-descriptions-item>
      <template #label>
        <div class="cell-item">
          <el-icon :style="iconStyle">
            <user />
          </el-icon>
          用戶名
        </div>
      </template>
      {{ curUser.username }}
    </el-descriptions-item>
    <el-descriptions-item>
      <template #label>
        <div class="cell-item">
          <el-icon :style="iconStyle">
            <iphone />
          </el-icon>
          年齡
        </div>
      </template>
      {{ curUser.age }}
    </el-descriptions-item>
    <el-descriptions-item>
      <template #label>
        <div class="cell-item">
          <el-icon :style="iconStyle">
            <location />
          </el-icon>
          籍貫
        </div>
      </template>
      {{ curUser.city }}
    </el-descriptions-item>
    <el-descriptions-item>
      <template #label>
        <div class="cell-item">
          <el-icon :style="iconStyle">
            <tickets />
          </el-icon>
          性別
        </div>
      </template>
      {{ curUser.sex }}
    </el-descriptions-item>
    <el-descriptions-item>
      <template #label>
        <div class="cell-item">
          <el-icon :style="iconStyle">
            <office-building />
          </el-icon>
          住址
        </div>
      </template>
      {{ curUser.address }}
    </el-descriptions-item>
  </el-descriptions>
</template>

<script setup>
import { ref, onMounted } from "vue";
import { useRoute } from "vue-router";
import { userList } from "@/utils/data";

const route = useRoute();
const initialUser = {
  date: "",
  username: "",
  sex: "",
  age: 18,
  city: "",
  address: "",
  id: "",
};
const curUser = ref({ ...initialUser });
const goBack = async () => {
  await localStorage.setItem("TAB_COUNT", "1");
  await sessionStorage.removeItem("TAB_ID");
  window.close();
};
const iconStyle = {
  fontSize: "20px",
  color: "#409eff",
};

const channel = new BroadcastChannel("user_detail");
channel.addEventListener("message", (event) => {
  console.log("接收到消息:", event.data);
  sessionStorage.removeItem("TAB_ID");
  const curUserId = event.data;
  const user = userList.find((user) => user.id === curUserId);
  if (user) {
    curUser.value = user;
  }
});

onMounted(() => {
  const curUserId = sessionStorage.getItem("TAB_ID");
  if (curUserId) {
    const user = userList.find((user) => user.id === curUserId);
    if (user) {
      curUser.value = user;
    }
  }
  // 監(jiān)聽頁面卸載事件
  window.addEventListener("unload", async () => {
    await localStorage.setItem("TAB_COUNT", "1");
    await sessionStorage.removeItem("TAB_ID");
  });
});
</script>

實(shí)現(xiàn)效果

實(shí)現(xiàn)原理

使用BroadcastChannel創(chuàng)建通道進(jìn)行瀏覽器標(biāo)簽頁通信,利用瀏覽器本地緩存記錄標(biāo)簽頁打開數(shù)量,如果數(shù)量為1(僅有列表頁,沒有詳情頁),則使用window.open打開;反之如果數(shù)量為2,則使用BroadcastChannel通道發(fā)送消息實(shí)現(xiàn)頁面數(shù)據(jù)更新;

BroadcastChannel和postMessage區(qū)別

相同點(diǎn):

  • 都可在不同頁面之間,進(jìn)行信息通訊

不同點(diǎn):

  • BroadcastChannel只可用于同源的不同頁面;
  • postmessage可以任何源

1.BroadcastChannel使用方法

// 實(shí)例BroadcastChannel
const myChannel = new BroadcastChannel('aa');
// 發(fā)送信息
myChannel.postMessage('發(fā)送的某些數(shù)據(jù)');
myChannel.onmessage = function(e){
    // 接收到的消息
    console.log(e.data);
}
// 關(guān)閉鏈接
myChannel.close();

2.postMessage使用方法

//給其他源發(fā)送postMessage
otherWindow.postMessage(message, targetOrigin, [transfer]);
****解釋********
otherWindow:其他窗口的一個(gè)引用,比如 iframe 的 contentWindow 屬性、執(zhí)行 window.open 返回的窗口對(duì)象、或者是命名過或數(shù)值索引的 window.frames
message:將要發(fā)送到其他 window的數(shù)據(jù)。
targetOrigin:指定哪些窗口能接收到消息事件,其值可以是 *(表示無限制)或者一個(gè) URI。
transfer:可選,是一串和 message 同時(shí)傳遞的 Transferable 對(duì)象。這些對(duì)象的所有權(quán)將被轉(zhuǎn)移給消息的接收方,而發(fā)送一方將不再保有所有權(quán)。
*****************
// 其他源的頁面,添加addEventlistener監(jiān)聽message
window.addEventListener('message', function (e) {  // 監(jiān)聽 message 事件
        messageEle.innerHTML = "從"+ e.origin +"收到消息: " + e.data;
    });

到此這篇關(guān)于JS中BroadcastChannel實(shí)現(xiàn)瀏覽器標(biāo)簽頁通信的文章就介紹到這了,更多相關(guān)JS BroadcastChannel瀏覽器標(biāo)簽頁通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

定远县| 汕头市| 阳西县| 舟山市| 雷山县| 贞丰县| 佛冈县| 革吉县| 大连市| 大安市| 政和县| 长沙市| 兰西县| 海宁市| 东城区| 宝兴县| 修武县| 望奎县| 拉萨市| 如皋市| 长丰县| 乌什县| 东乌| 长子县| 义乌市| 北安市| 佛坪县| 兴宁市| 都昌县| 砀山县| 都匀市| 宣化县| 宜黄县| 永济市| 皮山县| 冷水江市| 马山县| 离岛区| 纳雍县| 昌吉市| 广宁县|