詳解Vue3如何優(yōu)雅的監(jiān)聽localStorage變化
為什么要這樣做
原生的localStorage
只能監(jiān)聽同源地址下不同頁面的localStorage
變化,作為單頁面應(yīng)用,顯然不實(shí)用。所以我打算自定義一個hook
監(jiān)聽localStorage
的變化。
思路
首先我們需要重寫localStorage
下的所有方法,這樣在每個方法被使用的時候就可以被監(jiān)聽到了。
此時就需要一個事件機(jī)制,用于傳遞消息。
在Vue3
移除了$on
、$emit
事件接口后,我們可以借助第三方庫實(shí)現(xiàn):mitt
、tiny-emitter
.
不過我打算使用自己實(shí)現(xiàn)的中介者模式
作為通信方法。
實(shí)現(xiàn)
實(shí)現(xiàn)中介者模式
// 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) => { // 防止重復(fù)發(fā)布 if (!keys.includes(key)) keys.push(key); // 被修改就發(fā)布事件 sub.publish(key, value); window.localStorage.setItem(key, value); }, clear: () => { // 被刪除就每個key發(fā)布事件 keys.map((key) => sub.publish(key, undefined)); // 發(fā)布后清空記錄key的數(shù)組 keys.length = 0; window.localStorage.clear(); }, removeItem: (key: string) => { keys.splice(keys.indexOf(key), 1); // 被移除就發(fā)布 undefined sub.publish(key, undefined); window.localStorage.removeItem(key); }, key: window.localStorage.key, length: window.localStorage.length, };
實(shí)現(xiàn)useStorage hook
// 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; };
測試
使用localStorage
// One.vue // 使用localStorage import { watch } from "vue"; import { useStorage } from "./hook"; const key = useStorage("yourKey"); watch([key], (a) => console.log(a));
監(jiān)聽localStorage變化
// Two.vue // 監(jiān)聽localStorage <script setup lang="ts"> import { ref } from "vue"; import { localStorage } from "./hook"; const count = ref(0); </script> <template> <div> <button type="button" @click="$localStorage.setItem('a', count++);" > count is {{ count }} </button> </div> </template>
結(jié)果
到此這篇關(guān)于詳解Vue3如何優(yōu)雅的監(jiān)聽localStorage變化的文章就介紹到這了,更多相關(guān)Vue3監(jiān)聽localStorage變化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue之使用echarts圖表setOption多次很卡問題及解決
這篇文章主要介紹了vue之使用echarts圖表setOption多次很卡問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07Hexo已經(jīng)看膩了,來手把手教你使用VuePress搭建個人博客
vuepress是尤大大4月12日發(fā)布的一個全新的基于vue的靜態(tài)網(wǎng)站生成器,實(shí)際上就是一個vue的spa應(yīng)用,內(nèi)置webpack,可以用來寫文檔。這篇文章給大家介紹了VuePress搭建個人博客的過程,感興趣的朋友一起看看吧2018-04-04vue+webrtc(騰訊云) 實(shí)現(xiàn)直播功能的實(shí)踐
本文主要介紹了vue+webrtc(騰訊云) 實(shí)現(xiàn)直播功能的實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-11-11Vue自定義過濾器格式化數(shù)字三位加一逗號實(shí)現(xiàn)代碼
這篇文章主要介紹了Vue自定義過濾器格式化數(shù)字三位加一逗號的實(shí)現(xiàn)代碼,需要的朋友可以參考下2018-03-03Vue實(shí)現(xiàn)搜索結(jié)果高亮顯示關(guān)鍵字
這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)搜索結(jié)果高亮顯示關(guān)鍵字,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-05-05Vue3導(dǎo)航欄組件封裝實(shí)現(xiàn)方法
這篇文章主要為大家詳細(xì)介紹了Vue3導(dǎo)航欄組件封裝的實(shí)現(xiàn)方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09vue中使用webuploader做斷點(diǎn)續(xù)傳實(shí)現(xiàn)文件上傳功能
之前做的一個項目中,由于經(jīng)常上傳幾百兆的壓縮包,導(dǎo)致經(jīng)常上傳失敗,所以就找了webuploader插件做了斷點(diǎn)續(xù)傳,斷點(diǎn)續(xù)傳除了需要前端分片,也需要后臺去支持,所以做的時候做好對接協(xié)調(diào),所以本文就給大家詳細(xì)的介紹一下vue中如何使用webuploader做斷點(diǎn)續(xù)傳2023-07-07