vue 监听localStorage、sessionStorage变化

如何实时监测storage的变化

一、不同浏览器页签间的监听(sessionStorage、localstorage、vuex的变化都可以监听到)

使用场景:同一个浏览器,以用户最后一次登录账号为准(使用localStorage存储)。

mounted() {
    window.addEventListener('storage', (e) => {
      console.log("storage值发生变化后触发:", e)
    });
  },

弊端:同一个浏览器页签,修改storage的值,监听不到

二、同浏览器页签的监听(sessionStorage、localstorage均可)

使用场景:storage发生变化,执行某些方法。
main.js中:(sessionStarage雷同)

let orignalSetItem = window.localStorage.setItem;   // 原生localStorage.setItem方法
localStorage.setItem = function(key,newValue){
  let setItemEvent = new Event("setItemEvent");  // 重写注册setItem
  setItemEvent.key = key;                        
  setItemEvent.newValue = newValue;              
  window.dispatchEvent(setItemEvent);            // 派发setItem
  orignalSetItem.apply(this, arguments);         // 设置值
}

上面的方法在火狐浏览器上遇到了问题,即监听失效了!原因是因为火狐浏览器把我们重写的setItem方法当作字符串存下来了(见图1-1)详细解释看这里~

图1-1

因此我们使用Object.defineProperty去改写Storage的方法。

// 用闭包实现局部对象storage(注意Storage的方法都重写一遍,不然调用其对象原型方法会报错。)
var localStorageMock = (function(win) {
  var storage = win.localStorage;
  return {
      setItem: function(key, value) {
        var setItemEvent = new Event("setItemEvent");
        var oldValue = storage[key];
        setItemEvent.key = key;
        // 新旧值深度判断,派发监听事件
        if (oldValue !== value) {
            setItemEvent.newValue = value;
            setItemEvent.oldValue = oldValue;
            win.dispatchEvent(setItemEvent);
            storage[key] = value;
            return true;
        }
        return false;
      },
      getItem: function(key) {
        return storage[key];
      },
      removeItem: function(key) {
        storage[key] = null;
        return true;
      },
      clear: function() {
          storage.clear();
          return true;
      },
      key: function (index) {
          return storage.key(index);
      }
  };
}(window));

Object.defineProperty(window, 'localStorage', { value: localStorageMock, writable: true });

使用:

window.addEventListener("setItemEvent", (e) => {
    console.log("localStorage值发生变化后触发:", e.newValue);
});

弊端:不同浏览器页签(相同地址),修改storage的值,监听不到

三、浏览器页签的监听(sessionStorage、localstorage均可)

 mounted() {
    window.addEventListener('storage', (e) => {
      console.log("别的浏览器页签storage发生变化啦:", e)
    });
    window.addEventListener("setItemEvent", (e) => {
      console.log("localStorage值发生变化后触发:", e.newValue);
    });
  },

这样,不管是同浏览器页签还是不同浏览器页签,就都能监听到啦~

你可能感兴趣的:(vue 监听localStorage、sessionStorage变化)