Зачем это делать?
Собственный localStorage может прослушивать изменения только в одном и том же источнике на разных страницах. Однако для одностраничных приложений такой подход непрактичен. Поэтому я намерен создать собственный крючок для отслеживания изменений в localStorage.
Подход
Нам нужно переопределить все методы в localStorage, чтобы их можно было наблюдать при каждом использовании. Для этого требуется механизм событий для передачи сообщений.
Поскольку в Vue 3 удалены интерфейсы событий $on и $emit, мы можем использовать сторонние библиотеки, такие как 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) => { // Prevent duplicate publishing if (!keys.includes(key)) keys.push(key); // Publish an event if it's modified sub.publish(key, value); window.localStorage.setItem(key…