有没有办法在Vuejs'观察'本地存储?

art*_*071 18 javascript vue.js vue-resource vue-component vuejs2

我正在尝试关注本地存储:

模板:

<p>token - {{token}}</p>
Run Code Online (Sandbox Code Playgroud)

脚本:

computed: {
  token() {
    return localStorage.getItem('token');
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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

Cob*_*way 17

当然可以!我认为最好的做法是使用getter/setter语法来包装localstorage.

这是一个工作示例:

HTML:

<div id="app">
  {{token}}
  <button @click="token++"> + </button>
</div>
Run Code Online (Sandbox Code Playgroud)

JS:

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

还有一个JSFiddle.

  • 我已经尝试过了,当本地存储发生更改时无法进行反应。我正在尝试v-if是否存在本地存储项目。 (3认同)
  • 这样做的唯一原因是因为每次单击它时,都会调用获取值来检索,然后调用集合来修改。当其他源修改本地存储时,它不会做出反应。 (3认同)
  • @MattClimbs 每个人都会遇到这种情况,因为这就是本地存储的工作原理。/sf/ask/140762471/ (2认同)

Sal*_*lam 10

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

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

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

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

然后在您需要观看的地方执行以下操作:

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

  • 仅当更改是从同一选项卡进行时才有效,如果是这种情况,则所有其他事件总线实现也可以正常工作,并且优于晦涩的自定义 DOM 事件。 (3认同)
  • 另一个不错的部分是,您可以从普通 js 对象调用基于 vue 的响应。 (2认同)

arv*_*ve0 5

如果要避免样板化(getter / setter语法),请使用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>'
})
Run Code Online (Sandbox Code Playgroud)

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

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

  1. 添加一个mixininitialState在所有Vue实例中可用,并且
  2. 监视更改并将其存储。

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

  • 该存储库已存档。建议不要再使用此解决方案。 (2认同)

Luc*_*gan 5

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

他们提供了一个例子。鉴于此 html 模板

<template>
  <div id="app">
    My name is <input v-model="name">
  </div>
<template>
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 我认为它只在 'name' 更改时以一种方式起作用,但从另一侧(当 'localstorage.name' 更改时)不起作用。 (7认同)
  • 虽然这很简单,但这正是我正在寻找的,并且链接涉及更复杂的用途。谢谢 (2认同)
  • 是的。watch 只设置在 app 中的 `name` 属性上,而不是实际的 localstorage 对象。 (2认同)