vue 跨标签页的数据共享(即跨标签页通信)
跨标签页通信的常见方案
LocalStorage 或 SessionStorage
BroadCast Channel
Service Worker
Shared Worker
Window.postMessage()
Cookies
IndexedDB
什么是跨标签页通信?
指在同一个浏览器窗口中的多个标签页之间进行数据交流和信息传递的过程。通常情况下,每个标签页都是一个独立的浏览器上下文,它们之间是相互隔离的,无法直接访问对方的数据或进行通信。
跨标签页通信的目的是允许这些相互隔离的标签页之间进行信息共享和交互。通过跨标签页通信,可以实现数据的共享、状态的同步、消息的传递等功能。
例如:在一个标签页中进行了某个操作,希望其他标签页能够及时获得相关的变化和通知,就需要使用跨标签页通信机制来实现这种交互。
跨标签页通信主要用于哪些需求?
① 数据共享:当多个标签页需要访问和共享相同的数据时,跨标签页通信可以用于在这些标签页之间传递数据,确保它们保持同步。
② 状态同步:在一些应用中,可能会有多个标签页用于展示相同的应用状态或会话状态。通过跨标签页通信,可以实现状态的同步,使得在一个标签页中的操作能够即时反映到其他标签页上。
③ 消息通知:跨标签页通信可以用于实现在一个标签页中发送消息,然后其他标签页接收并展示这些消息的功能。
④ 共享资源:在某些场景下,可能需要在多个标签页之间共享某些资源,如网络连接、音频/视频播放器等等。
⑤ 多窗口管理:对于一些具有多个窗口的应用,跨标签页通信可以用于实现窗口之间的联动和数据同步。
常见方案的实现
方案一:LocalStorage 或 SessionStorage
使用 Web 存储机制( LocalStorage 或 SessionStorage )可以在不同标签页之间共享数据。一个标签页可以将数据存储在 LocalStorage 或 SessionStorage 中,其他标签页可以监听存储事件来获取更新的数据。
/* 在一个标签页中写入数据到 LocalStorage 或 SessionStorage */
localStorage.setItem('shareData', '标签页111');
// sessionStorage.setItem('shareData', '标签页111');/* 在其他标签页中监听存储事件,并获取更新的数据 */
window.addEventListener('storage', function(event) {if (event.key === 'shareData') {const newData = event.newValue;console.log('收到的更新数据:', newData);}
});/* 在另一个标签页中更新数据到 LocalStorage 或 SessionStorage */
localStorage.setItem('shareData', '标签页222');
// sessionStorage.setItem('shareData', '标签页222');
首先在一个标签页中通过 localStorage.setItem() 或 sessionStorage.setItem() 方法将数据写入到 LocalStorage 或 SessionStorage 中。
然后在其他标签页中通过监听 storage 事件来捕获存储事件,并判断事件的 key 是否为我们共享的数据 sharedData,如果是,则获取更新的数据 newValue 并进行处理。
最后在另一个标签页中通过 localStorage.setItem() 或 sessionStorage.setItem() 方法更新数据。
方案二:Broadcast Channel
Broadcast Channel API 允许不同标签页之间通过共享的通道进行消息广播和接收。一个标签页可以通过通道发送消息,其他订阅了相同通道的标签页可以接收到这些消息。
在发送消息的标签页中
/* 创建一个广播通道 */
const channelObj = new BroadcastChannel('televiseChannel');// 发送消息
channelObj.postMessage('标签页111');
在接收消息的标签页中
/* 创建一个广播通道 */
const channelObj = new BroadcastChannel('televiseChannel');// 监听消息事件
channelObj.onmessage = function(event) {const newData = event.data;console.log('收到的更新数据:', newData);
};
在发送消息的标签页中创建一个 Broadcast Channel,并指定一个唯一的通道名称(这里使用'televiseChannel')。通过 channelObj.postMessage() 方法发送消息到该通道。
在接收消息的标签页中,同样创建一个具有相同通道名称的 Broadcast Channel。然后通过为 channelObj.onmessage 赋值一个函数来监听消息事件。当接收到消息时,事件对象 event 中的 data 属性将包含发送的消息内容,我们可以在监听函数中获取并处理该消息。
方案三:Service Worker
Service Worker 是一种独立于网页的脚本,可以在后台运行,提供离线缓存和消息传递等功能。标签页可以通过 Service Worker 进行通信,发送消息和接收消息。
方案四:Shared Worker
Shared Worker 是一种在多个标签页之间共享的后台线程。标签页可以通过 SharedWorker 进行通信,发送消息和接收消息。这种方式需要使用 JavaScript 的 Worker API。
在发送消息的标签页中
/* 创建一个 SharedWorker */
const worker = new SharedWorker('worker.js');// 发送消息
worker.port.postMessage('标签页111');
在共享的 Worker 脚本文件 worker.js 中
/* 监听连接事件 */
self.onconnect = function(event) {const port = event.ports[0];// 监听消息事件port.onmessage = function(event) {const newData = event.data;console.log('收到的更新数据:', newData);};// 发送消息port.postMessage('你好啊!Worker');
};
在发送消息的标签页中创建一个 SharedWorker,并指定共享的 Worker 脚本文件路径为 'worker.js'。然后通过 worker.port.postMessage() 方法发送消息到 SharedWorker。
在共享的 Worker 脚本文件 worker.js 中,通过监听 self.onconnect 事件来捕获连接事件,并获取与标签页之间的通信端口 port。然后通过为 port.onmessage 赋值一个函数来监听消息事件。当接收到消息时,事件对象 event 中的 data 属性将包含发送的消息内容,我们可以在监听函数中获取并处理该消息。
方案五:Window.postMessage()
Window.postMessage() 方法允许在不同的窗口或标签页之间安全地传递消息。通过调用 postMessage() 方法并指定目标窗口的 origin,可以将消息发送到其他标签页,并通过监听 message 事件来接收消息。
在发送消息的标签页中
/* 监听消息事件 */
window.addEventListener('message', function(event) {// 确保消息来自预期的源if (event.origin !== 'http://example.com') return;const newData = event.data;console.log('收到的更新数据:', newData);
});// 发送消息到其他标签页
const targetWindow = window.open('http://example.com/otherpage', '_blank');
targetWindow.postMessage('标签页111', 'http://example.com');
在接收消息的标签页中
/* 监听消息事件 */
window.addEventListener('message', function(event) {// 确保消息来自预期的源if (event.origin !== 'http://example.com') return;const newData = event.data;console.log('收到的更新数据:', newData);// 回复消息event.source.postMessage('标签页222', event.origin);
});
在发送消息的标签页中通过使用 window.addEventListener('message', ...) 监听消息事件。在事件处理函数中,可以用 event.origin 来验证消息的来源是否符合预期。然后,可以用 event.data 获取到发送的消息内容,并进行相应的操作。
在发送消息的标签页中,用 window.open() 打开了一个新的标签页(http://example.com/otherpage),然后通用 targetWindow.postMessage() 向该标签页发送消息。在这里,我们指定了消息的目标窗口和预期的来源(即目标标签页的 URL)。
在接收消息的标签页中,同样通过 window.addEventListener('message', ...) 监听消息事件,并在事件处理函数中进行相应的操作。
方案六:Cookies
可以将需要共享的数据存储在 Cookies 中,并在不同的标签页之间读取和更新这些 Cookies。当一个标签页更新数据时,将数据写入到 Cookies 中,其他标签页可以通过监听 Cookies 变化事件或定时读取 Cookies 来获取最新的数据。
使用 Cookies 进行通信是一种简单的方法,但它主要用于在客户端和服务器之间传递数据,而不是直接实现跨标签页通信。Cookies 会自动在客户端和服务器之间进行传递,因此可以在不同的标签页之间共享数据。
在发送消息的标签页中
/* 设置 Cookie 值 */
document.cookie = 'shareData=标签页111';
在接收消息的标签页中
/* 获取 Cookie 值 */
const cookies = document.cookie;
const cookieArr = cookies.split(';');
const strField = 'shareData=';let newData = null;
for (let i = 0; i < cookieArr.length; i++) {const cookie = cookieArr[i].trim();if (cookie.startsWith(strField)) {newData = cookie.substring(strField.length, cookie.length);break;}
}
console.log('收到的更新数据:', newData);
方案七:IndexedDB
IndexedDB 是浏览器提供的一个客户端数据库,可以在不同的标签页之间存储和读取数据。一个标签页可以将数据写入 IndexedDB,其他标签页可以监听 IndexedDB 的变化事件或定时从 IndexedDB 中读取数据来实现数据的共享和状态的同步。
/* 打开或创建 IndexedDB 数据库 */
const request = indexedDB.open('dataBase', 1);/* 成功打开数据库 */
request.onsuccess = function(event) {const db = event.target.result;// 创建一个对象存储空间(类似表)const objectStore = db.createObjectStore('messages', { keyPath: 'id', autoIncrement: true });// 添加一条消息到对象存储空间const message = { text: 'Hello, World!' };const addRequest = objectStore.add(message);addRequest.onsuccess = function(event) {console.log('消息已添加到IndexedDB');};addRequest.onerror = function(event) {console.error('添加消息到IndexedDB时发生错误');};// 从对象存储空间获取所有消息const getAllRequest = objectStore.getAll();getAllRequest.onsuccess = function(event) {const messages = event.target.result;console.log('所有消息:', messages);};getAllRequest.onerror = function(event) {console.error('获取消息时发生错误');};
};/* 打开或创建数据库时发生错误 */
request.onerror = function(event) {console.error('打开/创建数据库时发生错误');
};/* 数据库版本变更 */
request.onupgradeneeded = function(event) {const db = event.target.result;// 创建一个对象存储空间const objectStore = db.createObjectStore('messages', { keyPath: 'id', autoIncrement: true });console.log('数据库版本已更新');
};
相关文章:
vue 跨标签页的数据共享(即跨标签页通信)
跨标签页通信的常见方案 LocalStorage 或 SessionStorage BroadCast Channel Service Worker Shared Worker Window.postMessage() Cookies IndexedDB 什么是跨标签页通信? 指在同一个浏览器窗口中的多个标签页之间进行数据交流和信息传递的过程。通常情况…...
什么是拉宾-斯科特定理?
拉宾-斯科特定理(Rabin-Scott theorem )是数学上最深刻的数学结果之一。拉宾-斯科特定理是人们最喜欢的计算机科学概念之一。 当正确理解拉宾-斯科特定理时,它会以一种相当基本的方式改变你对现实的看法。然而,它典型的教科书式的呈现方式掩盖了这种深…...

Java并发编程第11讲——AQS设计思想及核心源码分析
Java并发包(JUC)中提供了很多并发工具,比如前面介绍过的ReentrantLock、ReentrantReadWriteLock、CountDownLatch、Semaphore、FutureTask等锁或者同步部件,它们的实现都用到了一个共同的基类——AbstractQueuedSynchronizer&…...

什么是数据库?数据库有哪些基本分类和主要特点?
数据库是以某种有组织的方式存储的数据集合。本文从数据库的基本概念出发,详细解读了数据库的主要类别和基本特点,并就大模型时代备受瞩目的数据库类型——向量数据库进行了深度剖析,供大家在了解数据库领域的基本概念时起到一点参考作用。 …...

flutter显示出底部控件的引导页
需求:同一个页面的两个不同的入口,同一个控件的位置有变化,显示引导页时对应这个控件的引导内容的位置也需要改变;同时半透明底部显示出真实的页面内容。 这样的需要如果切图然后再往页面上贴位置无法精确的对准。 思路࿱…...
常用设计模式——模板方法模式
什么是模板方法模式 模板方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 主要解决:一些方法通用,却要在每一个子类都重写这些方法…...

idea使用git删除本地提交(未推送)
1、找到reset head 2、打开弹窗,在HEAD后面输入^ 结果为HEAD^ 注释: Reset Type 有三种: Mixed(默认方式),保留本地源码,回退 commit 和 index 信息,最常用的方式Soft 回退到某个版本…...

centos 7部署Mysql8.0主从
Mysql官网中关于部署主从的网址 环境准备: 搭建虚拟机和安装Mysql之前的文章中已经涉及,在此不再赘述。 主从IPMysql账号密码主192.168.213.4root/Root1234!从192.168.213.5root/Root1234! 1、主数据库设置 配置my.cnf 一般存放于/etc/。 主从配…...
asp.net docker-compose添加es search
打开docker-compose.yml添加 es-search:image: docker.elastic.co/elasticsearch/elasticsearch:7.17.14 打开docker-compose.override.yml添加 es-search:volumes:- data01:/usr/share/elasticsearch/dataports:- 9200:9200 docker集群中添加es search成功...

工业路由器网关的网络协议之NAT技术
在物联网通讯领域,NAT技术能将内网的一个私有IP转换成一个公网IP去接入互联网,解决组建局域网络时私有IP地址无法在公网上进行路由的问题。 NAT(Network Address Translation)的三种方式: 静态NAT 1、一个私有IP对应…...
【亲测可用】SpringBoot使用Redis的Lettuce连接池报RedisCommandTimeoutException
目录 一、问题详情 二、根本原因 三、解决方案 一、问题详情 在最近新项目的开发当中,当项目刚启动的时候访问Redis服务一切正常,但是过了几分钟后再次访问Redis就报如下错误。 Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutExcept…...
When Urban Region Profiling Meets Large Language Models
本文是LLM系列文章,针对《When Urban Region Profiling Meets Large Language Models》的翻译。 当城市区域轮廓遇到大型语言模型时 摘要1 引言2 前言3 方法4 实验5 结论与未来工作 摘要 基于网络数据的城市区域概况对城市规划和可持续发展至关重要。我们见证了LL…...
【python】最大的偶数
题目: """ 给出一个由非负整数组成的序列 A (A1,A2,A3,....,Av)。这个序列的长度为N判断是否存在一个偶数可以表示为在A中两个不同元素的和。若存在,找到最大的偶数,否则输出”-…...

QT 实现两款自定义的温度计/湿度控件
文章目录 0 引入1、带有标尺的温度/湿度计控件1.头文件2.核心代码 2、竖起来的温度/湿度计控件1.头文件2.实现 3、引用 0 引入 QT原生控件没有实现如仪表盘或者温度计的控件,只好自己实现,文章代码部分参考引用的文章。直接上图 图一 带有标尺的温度计…...
Fourier分析导论——第4章——Fourier级数的一些应用(E.M. Stein R. Shakarchi)
第 4 章 傅里叶级数的一些应用 Fourier series and analogous expansions intervene very naturally in the general theory of curves and surfaces. In effect, this theory, conceived from the point of view of analysis, deals obviously with the study of arbitra…...
c语言使用fdk_aac库对aac音频解码为pcm
//示例为adts的aac流数据(adts数据可以每一包都可以独立解析不需要拼凑) //解码数据的采样率同解码前的采样率,如果不满足需求,需要对数据进行重采样 #include <aacdecoder_lib.h>int m_fd -1; int m_fd2 -1;void aac2pc…...
zustand管理工具--React
npm i zustand 1.函数参数必须返回一个对象 对象内部编写状态数据和方法 2.set是用来修改数据的专门方法必须调用它来修改数据 import { useEffect } from "react"; import { create } from "zustand";// 1. 创建store const goodsStore create((set) …...

Elasticsearch内存分析
文章目录 Elasticsearch JVM内存由哪些部分组成Indexing BufferNode Query CacheShard Request CacheField Data CacheSegments Cache查询 非堆内存内存压力mat分析es的jvm缓存监控 Elasticsearch JVM内存由哪些部分组成 官方建议Elasticsearch设置堆内存为32G,因为…...

Alert警告提示(antd-design组件库)简单使用
1.Alert警告提示 警告提示,展现需要关注的信息。 2.何时使用 当某个页面需要向用户显示警告的信息时。 非浮层的静态展现形式,始终展现,不会自动消失,用户可以点击关闭。 组件代码来自: 警告提示 Alert - Ant Design 3…...

Linux提权方法总结
1、内核漏洞提权 利用内核漏洞提取一般三个环节:首先对目标系统进行信息收集,获取系统内核信息及版本信息 第二步,根据内核版本获取对应的漏洞以及exp 第三步,使用exp对目标进行攻击,完成提权 注:此处可…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...

Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统
Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...
Java 与 MySQL 性能优化:MySQL 慢 SQL 诊断与分析方法详解
文章目录 一、开启慢查询日志,定位耗时SQL1.1 查看慢查询日志是否开启1.2 临时开启慢查询日志1.3 永久开启慢查询日志1.4 分析慢查询日志 二、使用EXPLAIN分析SQL执行计划2.1 EXPLAIN的基本使用2.2 EXPLAIN分析案例2.3 根据EXPLAIN结果优化SQL 三、使用SHOW PROFILE…...
深入浅出WebGL:在浏览器中解锁3D世界的魔法钥匙
WebGL:在浏览器中解锁3D世界的魔法钥匙 引言:网页的边界正在消失 在数字化浪潮的推动下,网页早已不再是静态信息的展示窗口。如今,我们可以在浏览器中体验逼真的3D游戏、交互式数据可视化、虚拟实验室,甚至沉浸式的V…...

Mac flutter环境搭建
一、下载flutter sdk 制作 Android 应用 | Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 1、查看mac电脑处理器选择sdk 2、解压 unzip ~/Downloads/flutter_macos_arm64_3.32.2-stable.zip \ -d ~/development/ 3、添加环境变量 命令行打开配置环境变量文件 ope…...

在Zenodo下载文件 用到googlecolab googledrive
方法:Figshare/Zenodo上的数据/文件下载不下来?尝试利用Google Colab :https://zhuanlan.zhihu.com/p/1898503078782674027 参考: 通过Colab&谷歌云下载Figshare数据,超级实用!!࿰…...