如何优雅地观察 Vue.js 3 中 localStorage 的变化?

照片由 Unsplash 上的 Thought Catalog 提供

为什么要这样做?

原生 localStorage 只能监听同源跨不同页面的变化。然而,对于单页面应用程序来说,这种方式并不实用。因此,我打算创建一个自定义钩子来监视 localStorage 中的变化。

方法

我们需要重写 localStorage 下的所有方法,以便无论何时使用它们都可以被观察到。这就需要一个事件机制来进行消息传递。

由于 Vue 3 删除了 o n 和 on和 onemit 事件接口,我们可以使用 mitt 或 tiny-emitter 等第三方库来实现此功能。

不过,我打算使用自己实现的中介模式作为通信方法。

解决方案

使用中介者模式的实现解决方案。

// mediator.ts
export interface MediatorProps {uuid?: number;publish?: (topic: string, ...args: unknown[]) => void;subscribe?: (topic: string, callback: (...args: unknown[]) => void) => void;
}const mediator = (function () {let topics = [],uuid = 0;function subscribe(topic: string, callback: (...args: unknown[]) => void) {uuid++;topics[topic] = topics[topic]? [...topics[topic], { callback, uuid }]: [{ callback, uuid }];}function publish(topic: string, ...args: unknown[]) {if (topics[topic]) {topics[topic].map((item) => item.callback(...args));}}return {install: function (obj: MediatorProps) {obj.uuid = uuid;obj.publish = publish;obj.subscribe = subscribe;return obj;},};
})();export default mediator;

然后我重写 localStorage 函数。

// localStorage.ts
import mediator from "./mediator";const keys: string[] = [];const createMediator = () => mediator.install({});const sub = createMediator();export const $localStorage = {getItem: (key: string) => {return window.localStorage.getItem(key);},setItem: (key: string, value: any) => {// 防止重复发布if (!keys.includes(key)) keys.push(key);// 发布事件(如果已修改)sub.publish(key, value);    window.localStorage.setItem(key, value);},clear: () => {// 为每个键清除时发布一个事件keys.map((key) => sub.publish(key, undefined));// 发布后,清除记录键值的数组keys.length = 0;window.localStorage.clear();},removeItem: (key: string) => {keys.splice(keys.indexOf(key), 1);// 删除时,发布undefinedsub.publish(key, undefined);window.localStorage.removeItem(key);},key: window.localStorage.key,length: window.localStorage.length,
};

第三,我实现了 useStorage 钩子

// useStorage.ts
import { ref } from "vue";
import mediator from "./mediator";
const createMediator = () => mediator.install({});export const useStorage = (key: string) => {const string = ref(null);const sub = createMediator();sub.subscribe(key, (value) => string.value = value);return string;
};

第四,我写的测试代码是这样的:

// One.vue
// use localStorage
import { watch } from "vue";
import { useStorage } from "./hook";const key = useStorage("imodd");watch([key], (a) => console.log(a));// Two.vue
// Observe localStorage

然后,结果是这样的

好了,这就是全部了。希望这篇文章能给你带来一点帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/222517.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开源IPad Pro应用IDE:使用SSH远程连接服务器进行云端编程开发

🔥博客主页: 小羊失眠啦. 🎥系列专栏:《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞👍收藏⭐评论✍️ 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,…

Linux——MySQL备份与恢复

一、数据库备份概述 1、数据备份的重要性 在企业中数据的价值至关重要,数据保障了企业业务的正常运行。因此.数据的安全性及数据的可靠性是运维的重中之重,任何数据的丢失都可能对企业产生严重的后果。通常情况下造成数据丢失的原因有如下几种…

10.CSS浮动

CSS浮动 1.介绍 在最初,浮动是用来实现文字环绕图片效果的,现在浮动是主流的页面布局方式之一 2.作用 让元素脱离标准流,同一级的浮动的元素可以并排在一排显示 3.元素浮动后的特点 脱离文档流不管浮动前是什么元素,浮动后&…

react+datav+echarts实现可视化数据大屏

📓最近有点闲,就学习了下react,没想到就把react学完了,觉得还不错,就打算出一把reactdatav的简易版可视化数据大屏供大家做个参考。 📓效果如下 1下载必要的框架 📓 react路由 npm install re…

网络安全渗透测试的相关理论和工具

网络安全 一、引言二、网络安全渗透测试的概念1、黑盒测试2、白盒测试3、灰盒测试 三、网络安全渗透测试的执行标准1、前期与客户的交流阶段1.1 渗透测试的目标网络1.2 进行渗透测试所使用的方法1.3 进行渗透测试所需要的条件1.4 渗透测试过程中的限制条件1.5 渗透测试的工期1.…

Ubuntu服务设置

0. systemd介绍 Linux系统的systemd是第一个运行的进程,用来创建系统的守护进程,管理整个Linux系统。systemd支持并行启动守护进程,systemd初始化整个系统所需的资源。 0.1 systemd基本命令 systemctl systemctl是systemd中最基本的命令&a…

[Kubernetes]2. k8s集群中部署基于nodejs golang的项目以及Pod、Deployment详解

一. 创建k8s部署的镜像 1.部署nodejs项目 (1).上传nodejs项目到节点node1 (2).压缩nodejs项目 (3).构建nodejsDockerfile 1).创建nodejsDockerfile 具体可参考:[Docker]十.Docker Swarm讲解,在/root下创建nodejsDockerfile,具体代码如下: FROM node #把压缩文件COPY到镜像的…

运筹学经典问题(七):旅行商问题(TSP)

问题描述 给定一系列城市和每对城市之间的距离,求解访问每座城市一次并回到起始城市的最短回路。 数学建模 集合: V V V:城市集合 常量: c i j c_{ij} cij​:城市 i i i到城市 j j j之间距离, i ≠ j i \neq j i…

WPF仿网易云搭建笔记(6):Style进阶详解

文章目录 专栏和Gitee仓库前言Style简单使用样式字典全局样式局部全局样式全局样式穿透 专栏和Gitee仓库 WPF仿网易云 Gitee仓库 WPF仿网易云 CSDN博客专栏 前言 WPF想要批量设置样式属性,一共有3个方法 Style样式Template控件模板DataTemplate数据模板 WPF 零基础…

每日一题2023.12.14|LeetCode3.无重复字符的最长子串

leetcode3.无重复字符的最长字串 连接:https://leetcode.cn/problems/longest-substring-without-repeating-characters/description/ 滑动窗口 找出字符串中不含重复字符的最长子串,由于最长子串是连续的,所以可以利用滑动窗口来做。窗口内的字符都是…

小区生活污水处理设备生产厂家讲解

小区生活污水处理设备生产厂家讲解 工艺流程讲解 1.进水井 进水井在处理系统中起到关键作用。它设置了溢流口和进水闸门,当来水量超过系统负荷或者系统发生故障时,可以关闭进水闸门,以防止污水直接进入河道或市政管网。这一步骤确保了系统的稳…

Windows下ping IP+端口的方法

有两种方法: 1. windows 开通 telnet 参考: https://zhuanlan.zhihu.com/p/570982111 2. 安装插件 参考:Windows下ping IP端口的方法 推荐使用第二种。

JVM-接口响应时间很长解决办法

问题 在程序运行过程中,发现有几个接口的响应时间特别长,需要快速定位到是哪一个方法的代码执行过程中出现了性能问题。 解决思路 已经确定是某个接口性能出现了问题,但是由于方法嵌套比较深,需要借助于算法定位到具体的方法。 A…

linux脚本中 #!/bin/sh、#!/bin/bash

我们通常看到的脚本文件总是有以下这样的开头: #!/bin/bash本文解释一下这是什么,以及为什么要写它。 首先解释一下 #! ,因为 #!有个专有的名词,叫 shebang 发音类似中文的 “蛇棒” 。为什么叫 shebang 呢? 首先 #…

综合实验:期末

实验要求: 一.物理连接 实验分2个组进行,使用思科模拟软件。每个同学模拟两个组。每个组选用一台路由器、一台三层交换机和一台二层交换机。要求按下图拓扑进行连接。如下图:最上端设备为核心交换机,按老师要求配置&a…

C# WPF上位机开发(动态添加控件)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 写图形界面软件的时候,我们经常会遇到一种情况。那就是图形界面上面,显示的控件可能是不定的。有可能多,也有可…

量子计算对密码学的威胁及应对方式

PrimiHub一款由密码学专家团队打造的开源隐私计算平台,专注于分享数据安全、密码学、联邦学习、同态加密等隐私计算领域的技术和内容。 当量子计算机问世时,许多加密方式将慢慢失去效果。本文将阐述原因以及正在研究的后量子密码学,以帮助人们…

Unity | Shader基础知识(第五集:案例<小彩球>)

目录 一、本节介绍 1 上集回顾 2 本节介绍 二、原理分析 1 现实中出现彩色的原因 2 软件里的彩色的原理 3 方案 三、 实现数字由【-1,1】映射为【0,1】 1 结论 2 原理 四、代码实现 1 注意事项 2 详解结构体appdata_base 3 接收数据 4 映射数据 5 输出给SV_TAR…

天猫数据平台-淘宝天猫数据-天猫销售数据分析:11月天猫平台滑雪运动装备行业销量翻倍!

随着天气变冷、冬季来临,迎来了疫情后的首个滑雪季,加之自冬奥会结束以来,大众参与冰雪运动的热度持续攀升,因此,冰雪运动的需求正集中释放。 根据相关数据显示,11月以来,全国滑雪场门票预订量较…

阿里云人工智能平台PAI多篇论文入选EMNLP 2023

近期,阿里云人工智能平台PAI主导的多篇论文在EMNLP2023上入选。EMNLP是人工智能自然语言处理领域的顶级国际会议,聚焦于自然语言处理技术在各个应用场景的学术研究,尤其重视自然语言处理的实证研究。该会议曾推动了预训练语言模型、文本挖掘、…