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

Vue實現(xiàn)多窗口數(shù)據(jù)實時同步的三種常規(guī)方案詳解

 更新時間:2025年11月03日 15:17:01   作者:拉不動的豬  
要實現(xiàn)多窗口(或多標(biāo)簽頁)數(shù)據(jù)實時同步(無需刷新),核心是利用?瀏覽器跨窗口通信能力?結(jié)合?狀態(tài)管理,本文將介紹三種常規(guī)方案,希望對大家有所幫助

要實現(xiàn)多窗口(或多標(biāo)簽頁)數(shù)據(jù)實時同步(無需刷新),核心是利用 瀏覽器跨窗口通信能力 結(jié)合 狀態(tài)管理,讓一個窗口的數(shù)據(jù)變化實時通知到其他窗口。以下是具體實現(xiàn)方案,按「通用性 + 復(fù)雜度」排序:

一、核心原理:瀏覽器跨窗口通信方案

瀏覽器提供了 3 種主流的跨窗口通信方式,均支持同源(同協(xié)議、同域名、同端口)下的窗口數(shù)據(jù)同步:

方案核心 API優(yōu)點缺點適用場景
Broadcast Channelnew BroadcastChannel()極簡(一行代碼發(fā)送 / 接收)、性能好不支持 IE(移動端 / 現(xiàn)代瀏覽器均支持)同源多窗口 / 多標(biāo)簽頁同步
LocalStorage 監(jiān)聽window.addEventListener('storage')兼容性極強(支持所有瀏覽器)依賴存儲事件(需修改 localStorage)需兼容舊瀏覽器的場景
SharedWorkernew SharedWorker()支持復(fù)雜邏輯(如實時計算、長連接)實現(xiàn)稍復(fù)雜(需單獨寫 Worker 文件)多窗口需共享復(fù)雜業(yè)務(wù)邏輯

二、具體實現(xiàn)方案(推薦優(yōu)先用 Broadcast Channel)

以「閱讀數(shù)量同步」為例,3 種方案的完整代碼如下,可直接復(fù)制使用:

方案 1:Broadcast Channel(最簡單,推薦)

原理:創(chuàng)建一個「廣播頻道」,所有窗口加入該頻道;當(dāng)一個窗口的閱讀數(shù)變化時,向頻道發(fā)送消息,其他窗口接收消息后更新數(shù)據(jù)。

1. 封裝通信工具(可復(fù)用)

創(chuàng)建 src/utils/channel.js,統(tǒng)一管理廣播頻道:

// 1. 創(chuàng)建全局唯一的廣播頻道(頻道名自定義,需確保所有窗口一致)
const channel = new BroadcastChannel('read-count-sync');

// 2. 發(fā)送消息(數(shù)據(jù)變化時調(diào)用,如閱讀數(shù)+1)
export function sendReadCount(count) {
  channel.postMessage({
    type: 'READ_COUNT_UPDATE', // 消息類型(區(qū)分不同同步內(nèi)容)
    data: count // 要同步的閱讀數(shù)
  });
}

// 3. 接收消息(其他窗口發(fā)送消息時觸發(fā),用于更新本地數(shù)據(jù))
export function onReadCountUpdate(callback) {
  // 監(jiān)聽頻道消息
  channel.onmessage = (e) => {
    // 只處理閱讀數(shù)更新的消息
    if (e.data.type === 'READ_COUNT_UPDATE') {
      callback(e.data.data); // 把最新的閱讀數(shù)傳給回調(diào)函數(shù)
    }
  };

  // 銷毀頻道(避免內(nèi)存泄漏,在組件卸載時調(diào)用)
  return () => {
    channel.close();
  };
}

2. 窗口 A(閱讀操作窗口):發(fā)送數(shù)據(jù)變化

當(dāng)用戶在窗口 A 閱讀時,更新本地閱讀數(shù),并通過廣播通知其他窗口:

<template>
  <div class="read-page">
    <h2>當(dāng)前閱讀數(shù):{{ readCount }}</h2>
    <button @click="handleRead">點擊閱讀(+1)</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { sendReadCount } from '@/utils/channel';

// 本地閱讀數(shù)狀態(tài)(初始值可從接口/緩存獲取)
const readCount = ref(0);

// 閱讀操作:更新本地數(shù)據(jù) + 廣播通知其他窗口
const handleRead = () => {
  readCount.value += 1;
  // 發(fā)送最新的閱讀數(shù)到廣播頻道
  sendReadCount(readCount.value);
};
</script>

3. 窗口 B(需同步的窗口):接收數(shù)據(jù)并更新

窗口 B 初始化時監(jiān)聽廣播,收到消息后更新本地彈框的閱讀數(shù):

<template>
  <!-- 彈框組件:展示閱讀數(shù) -->
  <van-dialog v-model:show="dialogShow" title="閱讀統(tǒng)計">
    <p>當(dāng)前閱讀數(shù):{{ readCount }}</p>
  </van-dialog>
</template>

<script setup>
import { ref, onUnmounted } from 'vue';
import { onReadCountUpdate } from '@/utils/channel';

// 彈框顯示狀態(tài)(假設(shè)默認(rèn)打開)
const dialogShow = ref(true);
// 本地閱讀數(shù)狀態(tài)(初始值可從接口/緩存獲?。?
const readCount = ref(0);

// 監(jiān)聽閱讀數(shù)更新:收到其他窗口的消息后,更新本地數(shù)據(jù)
const destroyChannel = onReadCountUpdate((newCount) => {
  readCount.value = newCount; // 無需刷新,實時更新彈框內(nèi)容
});

// 組件卸載時銷毀廣播頻道(避免內(nèi)存泄漏)
onUnmounted(() => {
  destroyChannel();
});
</script>

方案 2:LocalStorage 監(jiān)聽(兼容所有瀏覽器)

原理:LocalStorage 是同源窗口共享的存儲;當(dāng)一個窗口修改 LocalStorage 時,其他窗口會觸發(fā) storage 事件,通過監(jiān)聽該事件同步數(shù)據(jù)。

1. 封裝工具(src/utils/storageSync.js)

// 存儲的 key(自定義,需所有窗口一致)
const READ_COUNT_KEY = 'read-count';

// 1. 更新閱讀數(shù)并觸發(fā) storage 事件
export function updateReadCount(count) {
  // 修改 LocalStorage(會觸發(fā)其他窗口的 storage 事件)
  localStorage.setItem(READ_COUNT_KEY, JSON.stringify({
    value: count,
    timestamp: Date.now() // 避免舊數(shù)據(jù)覆蓋(可選)
  }));
}

// 2. 監(jiān)聽閱讀數(shù)變化
export function onReadCountChange(callback) {
  // 監(jiān)聽 storage 事件
  const handleStorage = (e) => {
    // 只處理閱讀數(shù)相關(guān)的存儲變化
    if (e.key === READ_COUNT_KEY) {
      const { value } = JSON.parse(e.newValue); // 最新的閱讀數(shù)
      callback(value);
    }
  };

  window.addEventListener('storage', handleStorage);

  // 移除監(jiān)聽(組件卸載時調(diào)用)
  return () => {
    window.removeEventListener('storage', handleStorage);
  };
}

// 3. 獲取當(dāng)前閱讀數(shù)(初始化時用)
export function getCurrentReadCount() {
  const data = localStorage.getItem(READ_COUNT_KEY);
  return data ? JSON.parse(data).value : 0;
}

2. 窗口 A(閱讀操作)

<script setup>
import { ref } from 'vue';
import { updateReadCount, getCurrentReadCount } from '@/utils/storageSync';

// 初始化:從 LocalStorage 獲取當(dāng)前閱讀數(shù)
const readCount = ref(getCurrentReadCount());

const handleRead = () => {
  readCount.value += 1;
  // 更新 LocalStorage,觸發(fā)其他窗口同步
  updateReadCount(readCount.value);
};
</script>

3. 窗口 B(同步窗口)

<script setup>
import { ref, onUnmounted } from 'vue';
import { onReadCountChange, getCurrentReadCount } from '@/utils/storageSync';

const dialogShow = ref(true);
// 初始化:從 LocalStorage 獲取初始值
const readCount = ref(getCurrentReadCount());

// 監(jiān)聽 storage 事件,同步數(shù)據(jù)
const removeListener = onReadCountChange((newCount) => {
  readCount.value = newCount; // 實時更新彈框
});

// 組件卸載時移除監(jiān)聽
onUnmounted(() => {
  removeListener();
});
</script>

注意storage 事件 只在其他窗口修改 LocalStorage 時觸發(fā),當(dāng)前窗口修改不會觸發(fā)(需手動更新本地數(shù)據(jù),如上代碼已處理)。

方案 3:SharedWorker(復(fù)雜場景用)

原理:創(chuàng)建一個共享的 Worker 線程,所有窗口通過 Worker 通信;Worker 作為「中間件」轉(zhuǎn)發(fā)數(shù)據(jù),支持更復(fù)雜的邏輯(如統(tǒng)計所有窗口的閱讀總數(shù))。

1. 創(chuàng)建 Worker 文件(src/workers/readSync.worker.js)

// Worker 線程:管理所有窗口的連接和消息轉(zhuǎn)發(fā)
const connections = new Set(); // 存儲所有窗口的連接

// 監(jiān)聽窗口連接
self.onconnect = (e) => {
  const port = e.ports[0]; // 獲取當(dāng)前窗口的通信端口
  connections.add(port); // 加入連接集合

  // 監(jiān)聽窗口發(fā)送的消息
  port.onmessage = (msg) => {
    if (msg.data.type === 'READ_COUNT_UPDATE') {
      // 轉(zhuǎn)發(fā)消息到所有其他窗口
      connections.forEach(conn => {
        if (conn !== port) { // 不發(fā)給自己
          conn.postMessage(msg.data);
        }
      });
    }
  };

  // 窗口斷開連接時移除
  port.onmessageerror = () => {
    connections.delete(port);
  };
  port.onerror = () => {
    connections.delete(port);
  };
};

2. 封裝工具(src/utils/workerSync.js)

// 1. 創(chuàng)建 SharedWorker 實例
const worker = new SharedWorker(new URL('@/workers/readSync.worker.js', import.meta.url));
const port = worker.port; // 獲取通信端口
port.start(); // 啟動端口通信

// 2. 發(fā)送閱讀數(shù)更新
export function sendReadCount(count) {
  port.postMessage({
    type: 'READ_COUNT_UPDATE',
    data: count
  });
}

// 3. 接收其他窗口的更新
export function onReadCountUpdate(callback) {
  port.onmessage = (e) => {
    if (e.data.type === 'READ_COUNT_UPDATE') {
      callback(e.data.data);
    }
  };

  // 銷毀連接(組件卸載時調(diào)用)
  return () => {
    port.close();
  };
}

3. 窗口 A 和 B 的使用方式

與「方案 1(Broadcast Channel)」完全一致,只需替換導(dǎo)入的工具函數(shù)即可:

// 窗口 A 發(fā)送
import { sendReadCount } from '@/utils/workerSync';

// 窗口 B 接收
import { onReadCountUpdate } from '@/utils/workerSync';

三、注意

同源限制:以上 3 種方案均只支持 同源窗口(同協(xié)議、同域名、同端口);若跨域名(如 a.com 和 b.com),需用「跨域通信方案」(如 postMessage + iframe 橋接),但你的場景是同一項目的兩個窗口,無需考慮跨域。

初始值同步:新打開的窗口需先從「數(shù)據(jù)源」(如接口、LocalStorage)獲取初始閱讀數(shù),再監(jiān)聽后續(xù)變化;避免初始值為 0,導(dǎo)致同步前顯示錯誤。

內(nèi)存泄漏:所有監(jiān)聽事件(如 onmessage、storage)需在組件卸載時銷毀(如關(guān)閉廣播頻道、移除 storage 監(jiān)聽、關(guān)閉 Worker 端口),避免瀏覽器內(nèi)存占用過高。

數(shù)據(jù)一致性:若多個窗口同時修改閱讀數(shù)(如窗口 A 和 B 同時點擊閱讀),需確保數(shù)據(jù)不會沖突;可通過「時間戳」或「版本號」判斷數(shù)據(jù)新舊,或讓 Worker 統(tǒng)一處理計數(shù)(方案 3 適合)。

到此這篇關(guān)于Vue實現(xiàn)多窗口數(shù)據(jù)實時同步的三種常規(guī)方案詳解的文章就介紹到這了,更多相關(guān)Vue數(shù)據(jù)實時同步內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue-cli 3 全局過濾器的實例代碼詳解

    vue-cli 3 全局過濾器的實例代碼詳解

    這篇文章主要介紹了vue-cli 3 全局過濾器的實例代碼,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-06-06
  • 在Vue中使用SQLite數(shù)據(jù)庫的基礎(chǔ)應(yīng)用詳解

    在Vue中使用SQLite數(shù)據(jù)庫的基礎(chǔ)應(yīng)用詳解

    這篇文章主要為大家詳細(xì)介紹了在Vue中使用SQLite數(shù)據(jù)庫的基礎(chǔ)應(yīng)用,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-02-02
  • vue項目多租戶環(huán)境變量的設(shè)置

    vue項目多租戶環(huán)境變量的設(shè)置

    本文主要介紹了vue項目多租戶環(huán)境變量的設(shè)置,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • VeeValidate 的使用場景以及配置詳解

    VeeValidate 的使用場景以及配置詳解

    這篇文章主要介紹了VeeValidate 的使用場景以及配置詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • Vue3渲染器與編譯器深入淺析

    Vue3渲染器與編譯器深入淺析

    這篇文章主要為大家介紹了Vue3渲染器與編譯器深入淺析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • Vue基礎(chǔ)之偵聽器詳解

    Vue基礎(chǔ)之偵聽器詳解

    這篇文章主要為大家介紹了Vue基礎(chǔ)之偵聽器,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • Tree 組件搜索過濾功能實現(xiàn)干貨

    Tree 組件搜索過濾功能實現(xiàn)干貨

    這篇文章主要為大家介紹了 Tree組件搜索過濾功能實現(xiàn)干貨詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • Vue+Element UI實現(xiàn)下拉菜單的封裝

    Vue+Element UI實現(xiàn)下拉菜單的封裝

    這篇文章主要為大家詳細(xì)介紹了Vue+Element UI實現(xiàn)下拉菜單的封裝代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Vue中video標(biāo)簽如何實現(xiàn)不靜音自動播放

    Vue中video標(biāo)簽如何實現(xiàn)不靜音自動播放

    最近在做大屏展示需要在一開始播放引導(dǎo)視頻,產(chǎn)生自動播放需求,下面這篇文章主要給大家介紹了關(guān)于Vue中video標(biāo)簽如何實現(xiàn)不靜音自動播放的相關(guān)資料,需要的朋友可以參考下
    2023-01-01
  • vue2中如何使用swiper@5.4.5

    vue2中如何使用swiper@5.4.5

    這篇文章主要介紹了vue2中如何使用swiper@5.4.5問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12

最新評論

霍山县| 泉州市| 称多县| 博爱县| 盐亭县| 临桂县| 介休市| 收藏| 辽源市| 重庆市| 咸丰县| 大田县| 宿迁市| 民和| 灵宝市| 建昌县| 武夷山市| 诸城市| 呼玛县| 刚察县| 叶城县| 西华县| 福建省| 宁都县| 沧源| 辰溪县| 阿拉尔市| 古丈县| 包头市| 新化县| 沿河| 鹤山市| 吐鲁番市| 车致| 海门市| 罗定市| 五常市| 汉寿县| 绥阳县| 黄大仙区| 洮南市|