【问题标题】:Is there any way to 'watch' for localstorage in Vuejs?有没有办法在 Vuejs 中“观察”本地存储?
【发布时间】:2017-08-15 21:31:15
【问题描述】:

我正在尝试查看本地存储:

模板:

<p>token - {{token}}</p>

脚本:

computed: {
  token() {
    return localStorage.getItem('token');
  }
}

但是当token 改变时它不会改变。仅在刷新页面后。

有没有办法在不使用 Vuex 或状态管理的情况下解决这个问题?

【问题讨论】:

  • localStorage 不是响应式的,vuejs 可以检测到在实例中创建的属性的变化。
  • 如果您能解释为什么要这样做,有人可以提供帮助!

标签: javascript vue.js vuejs2 vue-component vue-resource


【解决方案1】:

当然!我认为最好的做法是使用getter / setter 语法来包装本地存储。

这是一个工作示例:

HTML:

<div id="app">
  {{token}}
  <button @click="token++"> + </button>
</div>

JS:

new Vue({
  el: '#app',
  data: function() {
    return {
      get token() {
        return localStorage.getItem('token') || 0;
      },
      set token(value) {
        localStorage.setItem('token', value);
      }
    };
  }
});

还有一个JSFiddle

【讨论】:

  • 很好的替代品,但在这种情况下,编译器会不断地反复点击以检查值是否发生变化。
  • 有趣的是,eslint 在第二个条目(getter 或 setter)上给了我错误 vue/no-dupe-keys。我用// eslint-disable-line vue/no-dupe-keys 压制了它,这似乎有效。
  • 此外,localStorage 似乎将整数转换为字符串,因此我需要运行 return parseInt(localStorage.getItem('userSessionIndex') || 0) 才能使其工作。其他人可能会也可能不会遇到这个问题。
  • @MattClimbs 每个人都会遇到这种情况,因为这就是本地存储的工作方式。 stackoverflow.com/questions/2010892/…
  • 这会起作用的唯一原因是因为每次单击它时,都会调用 get 值来检索,然后调用 set 来修改。当其他来源修改本地存储时,它不是响应式的。
【解决方案2】:

localStorage 不是响应式的,但我需要“观看”它,因为我的应用使用本地存储并且不想重写所有内容,所以这就是我使用 CustomEvent 所做的。

每当您向存储添加内容时,我都会发送 CustomEvent

localStorage.setItem('foo-key', 'data to store')

window.dispatchEvent(new CustomEvent('foo-key-localstorage-changed', {
  detail: {
    storage: localStorage.getItem('foo-key')
  }
}));

那么你需要在哪里观看它:

mounted() {
  window.addEventListener('foo-key-localstorage-changed', (event) => {
    this.data = event.detail.storage;
  });
},
data() {
  return {
    data: null,
  }
}

【讨论】:

【解决方案3】:

VueJs 网站有一个关于此的页面。 https://vuejs.org/v2/cookbook/client-side-storage.html

他们提供了一个例子。 给定这个 html 模板

<template>
  <div id="app">
    My name is <input v-model="name">
  </div>
<template>

他们提供了生命周期mounted 方法和观察者的这种用法。

const app = new Vue({
  el: '#app',
  data: {
    name: ''
  },
  mounted() {
    if (localStorage.name) {
      this.name = localStorage.name;
    }
  },
  watch: {
    name(newName) {
      localStorage.name = newName;
    }
  }
});

mounted 方法确保您从本地存储中设置 name(如果它已经存在),并且观察者允许您的组件在本地存储中的名称被修改时做出反应。这适用于添加或更改本地存储中的数据时,但如果有人手动擦除本地存储,Vue 将不会做出反应。

【讨论】:

  • 虽然这很简单,但这是我一直在寻找的,并且链接涉及更复杂的用途。谢谢
  • 我认为它仅在“名称”更改时以一种方式起作用,而不是从另一侧(当“localstorage.name”更改时)。
  • 是的。手表仅在应用程序中的name 属性上设置,而不是实际的本地存储对象。
【解决方案4】:

更新:不再维护 vue-persistent-state。如果它不适合您的账单,请分叉或查看其他地方。

如果您想避免样板文件(getter/setter-syntax),请使用vue-persistent-state 获取反应性持久状态。

例如:

import persistentState from 'vue-persistent-state';  

const initialState = {
  token: ''  // will get value from localStorage if found there
};
Vue.use(persistentState, initialState);

new Vue({
  template: '<p>token - {{token}}</p>'
})

现在token 可用作所有组件和 Vue 实例中的数据。对 this.token 的任何更改都将存储在 localStorage 中,您可以像在普通 Vue 应用中一样使用 this.token

插件基本上是watcher和localStorage.set。您可以阅读代码here。它

  1. 添加 mixin 以使 initialState 在所有 Vue 实例中可用,并且
  2. 监视更改并存储它们。

免责声明:我是vue-persistent-state的作者。

【讨论】:

  • 该存储库已归档。建议不要再使用这个解决方案了。
【解决方案5】:

你可以通过两种方式做到这一点,

  1. 通过使用vue-ls,然后在存储键上添加监听器,使用

        Vue.ls.on('token', callback)
    

        this.$ls.on('token', callback)
    
  2. 通过使用 DOM 的存储事件监听器:

        document.addEventListener('storage', storageListenerMethod);
    

【讨论】:

    【解决方案6】:

    LocalStorage 或 sessionStorage 不是反应式的。因此,您不能对它们设置观察者。例如,如果您使用 Vuex,一个解决方案是从存储状态存储值。 例如:

    SET_VALUE:(state,payload)=> {
        state.value = payload
        localStorage.setItem('name',state.value)
        or
        sessionStorage.setItem('name',state.value)
      }
    

    【讨论】:

      【解决方案7】:

      模板:

      <p>token - {{token}}</p>
      

      脚本:

      computed: {
        token() {
          return localStorage.getItem('token');
        }
      }
      
      mounted() {
        window.onstorage = () => {
          this.token = localStorage.getItem('token');
        }
      }
      

      不发出自定义事件(为此,它确实是多余的)。像魅力一样工作!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-10-12
        • 1970-01-01
        • 2019-03-26
        • 2021-04-01
        • 1970-01-01
        • 2018-06-04
        • 2015-01-07
        相关资源
        最近更新 更多