如何在 Vue 3 中使 localStorage 响应式

问题描述 投票:0回答:2

我试图用 v-if 隐藏导航栏中的一个元素。我将获取的布尔值保存在本地存储中。这是我第一次使用 Vue,过去 2 天我一直坚持这个,找不到它不起作用的原因。

<template>
    <router-link v-if="canAccessHistory" to="/activity" class="nav-button" @mouseenter="event => setHover(event, true)" @mouseleave="event => setHover(event, false)">
      <div :class="['nav-button-icon-container', activityActive ? 'nav-button-active' : '']">
        <i :class="['nav-button-icon', 'material-symbols-outlined', activityActive ? 'filled' : '']">history</i>
      </div>
      <p :class="['nav-text', activityActive ? 'text-active' : '']">Logboek</p>
    </router-link>
</template>

<script setup>
canAccessHistory = ref(localStorage.getItem('canAccessHistory'));
</script>

我尝试了所有方法,唯一一次不起作用是当我使用获取的数据时。我确保我的 api 返回一个布尔值。还在我的 js 中检查了它。

vue.js vuejs3
2个回答
1
投票

LocalStorage 不是响应式的(默认情况下),这意味着 Vue 不会注意到变化。

如果你想让它成为半反应式,你可以使用包中的

useStorage
函数
@vueuse/core

<script setup>
import { useStorage } from "@vueuse/core";

const saved = useStorage(
  "name-of-localstorage-key",
  "default value if nothing is saved already",
);
</script>

<template>
  <h1>{{ saved ?? "Nothing saved" }}</h1>

  <input v-model="saved" style="color: black" />
</template>

更改上例中的

saved
变量也会更改 localStorage 中的值。

使用

localStorage#getItem
直接写入 localStorage 不会改变
saved

更常见的方法是使用 Pinia 管理全局状态。

您首先创建一个商店:

// stores/auth/index.js

import { watch, ref } from "vue";
import { defineStore } from "pinia";

export const useAuthStore = defineStore("auth", () => {
  const canAccessHistory = ref(
    localStorage.getItem("canAccessHistory") === "true",
  );

  watch(canAccessHistory, () =>
    localStorage.setItem("canAccessHistory", canAccessHistory.value.toString()),
  );

  return {
    canAccessHistory,
  };
});

然后您可以在组件中导入商店:

<script setup>
import { storeToRefs } from "pinia";
import { ref, watch } from "vue";
import { useAuthStore } from "./auth";

const { canAccessHistory } = storeToRefs(useAuthStore());

function switchValue() {
  const newValue = !canAccessHistory.value;

  canAccessHistory.value = newValue;
}

// Only here to demonstrate
const rawFromLocalStorage = ref(
  localStorage.getItem("canAccessHistory") === "true",
);
watch(canAccessHistory, () => {
  rawFromLocalStorage.value =
    localStorage.getItem("canAccessHistory") === "true";
});
</script>

<template>
  <p>Value in store: {{ canAccessHistory }}</p>

  <p>Value in localStorage: {{ rawFromLocalStorage }}</p>

  <button type="button" @click="switchValue">Switch value</button>
</template>

可在此处找到工作演示

如果您对手动更新 localStorage 不感兴趣,您可以使用 Pinia 插件(如

pinia-plugin-persistedstate
)自动执行此操作。


0
投票

不确定从本地存储中获取什么样的值,但我假设它是布尔值。因此,您可能需要

computed
来监听本地存储上所做的更改。有关此内容的更多信息,请参阅此处

在脚本标签上导入函数。

import { computed } from 'vue';

然后要监听本地存储中的更改,请重构当前变量,如下所示:

const canAccessHistory = computed(() => localStorage.getItem('canAccessHistory') === true);

这将确保 Vue 监视您本地存储值的变化

© www.soinside.com 2019 - 2024. All rights reserved.