【问题标题】:Vue save localStorage for each items in listVue为列表中的每个项目保存localStorage
【发布时间】:2021-04-07 11:49:06
【问题描述】:

我正在进行一个项目,我在数据中硬编码一个列表(一些 DC 漫画)。我将 Vue.js 与 Tailwind 一起使用。每个漫画下都有两个按钮(一个是我买的漫画,另一个是我读的,有 2 个布尔值)。

我正在使用 localStorage 来保持我的进度,但问题就在这里... 我可以在buy = true 和/或read = true(或错误)上设置一些漫画,但我的网站保留了我修改的最后一项的本地存储密钥。所以无论我做什么,如果我在一个项目上设置 buy = true 或 false 和 read = false 或 false 然后我刷新页面,所有项目都有相同的修改。所以我不能单独对每个项目做任何事情。

我的物品组件模板:

<template>
  <div class="rounded-lg mx-2 md:mx-8 mb-8">
    <div class="relative shadow-lg rounded-lg">
      <img class="h-56 w-64 md:h-56 md:w-64 object-cover rounded-t-lg" :src=cover alt="cover">
      <h3 class="relative z-50 -mt-10 text-xs text-center uppercase py-1 font-medium bg-black bg-opacity-50 text-white">
        {{ collection }}
      </h3>
      <h3 class="relative z-50 text-xs rounded-b-lg text-center uppercase py-1 font-medium bg-black text-white">
        {{ title }}
      </h3>
      <!-- overlay -->
      <div v-if="buy === true" class="absolute flex items-center justify-center bg-gray-800 bg-opacity-75 p-2 rounded-lg w-full h-full z-50 top-0 right-0 flex justify-end space-x-4">
        <div class="h-10 w-10 text-white bg-green-500 rounded-full flex items-center justify-center">
          <svg class="w-6 h-6" viewBox="0 0 24 24" stroke-width="1.8" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
            <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
            <circle cx="9" cy="19" r="2" />
            <circle cx="17" cy="19" r="2" />
            <path d="M3 3h2l2 12a3 3 0 0 0 3 2h7a3 3 0 0 0 3 -2l1 -7h-15.2" />
          </svg>
        </div>
        <div v-if="read === true" class="h-10 w-10 text-white bg-green-500 rounded-full flex items-center justify-center">
          <svg class="w-8 h-8" viewBox="0 0 24 24" stroke-width="1.8" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
            <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
            <circle cx="12" cy="12" r="9" />
            <path d="M9 12l2 2l4 -4" />
          </svg>
        </div>
      </div>
    </div>
    <!-- buttons -->
    <div class="relative z-50 flex justify-end mt-2 space-x-6 mr-2">
      <button @click="toggleBuy" class="p-1 flex justify-center rounded-full text-gray-700 bg-gray-400 text-xs cursor-pointer uppercase font-medium focus:outline-none">
        <svg class="w-6 h-6" viewBox="0 0 24 24" stroke-width="1.7" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
          <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
          <circle cx="9" cy="19" r="2" />
          <circle cx="17" cy="19" r="2" />
          <path d="M3 3h2l2 12a3 3 0 0 0 3 2h7a3 3 0 0 0 3 -2l1 -7h-15.2" />
        </svg>
      </button>
      <button @click="toggleRead" class="p-1 flex justify-center rounded-full text-gray-700 bg-gray-400 text-xs cursor-pointer uppercase font-medium focus:outline-none">
        <svg class="w-6 h-6" viewBox="0 0 24 24" stroke-width="1.8" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
          <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
          <circle cx="12" cy="12" r="9" />
          <path d="M9 12l2 2l4 -4" />
        </svg>
      </button>
    </div>
  </div>
</template>

这是我的item组件的JS代码

<script lang="ts">
export default {
  name: 'Item',

  data() {
    return {
      buy: JSON.parse(localStorage.getItem('buyItem')),
      read: JSON.parse(localStorage.getItem('readItem'))
    }
  },

  props: {
    title: String,
    cover: String,
    collection: String
  },

  mounted() {
    if (localStorage.getItem('buyItem')) this.buy = JSON.parse(localStorage.getItem('buyItem'));
    if (localStorage.getItem('readItem')) this.read = JSON.parse(localStorage.getItem('readItem'));
  },

  methods: {
    toggleBuy() {
      this.buy = !this.buy
      localStorage.setItem('buyItem', JSON.stringify(this.buy))
    },
    toggleRead() {
      this.read = !this.read
      localStorage.setItem('readItem', JSON.stringify(this.read))
    }
  }
}
</script>

我的漫画的数据列在父组件中:

<template>
  <div class="bg-white shadow-lg rounded-xl px-8 pb-8 pt-4">

    <h2 class="ml-2 md:ml-8 mb-4 uppercase text-xl font-bold leading-7">
      New 52
    </h2>

    <div class="mx-auto">
      <div class="flex flex-wrap justify-center sm:justify-between">
        <Item
          v-for="item in renaissance"
          :key="item.id"
          :title="item.title"
          :cover="item.cover"
          :collection="item.collection"
        />
      </div>
    </div>
  </div>
</template>

<script lang="ts">
export default {
  name: 'Renaissance',

  data() {
    return {
      renaissance: [
        {
          key: 1,
          cover: "https://bdi.dlpdomain.com/album/9782365770415/couv/M385x862/batman-tome-1-la-cour-des-hiboux.jpg",
          title: "Tome 1: La Cour de Hiboux",
          collection: "new 52"
        },
        {
          key: 2,
          cover: "https://bdi.dlpdomain.com/album/9782365772068/couv/I500x800/batman-tome-2.jpg",
          title: "Tome 2: la nuit des hiboux",
          collection: "new 52"
        },
        {
          key: 3,
          cover: "https://bdi.dlpdomain.com/album/9791026815327/couv/M385x862/batman-amp-robin-integrale-tome-1.jpg",
          title: "Tome 1",
          collection: "batman & robin"
        },
        // there is more...
      ]
    }
  }
}
</script>

【问题讨论】:

    标签: vue.js boolean local-storage


    【解决方案1】:

    如果您进行以下更改,它应该可以工作。

    1. 您的 renaissance 数组当前没有名为 id 的属性,因此我会将您的 key 更改为 id 以便 :key="item.id" 有效

    2. id 传递给您的Item 组件,即:id="item.id"

    3. Item 组件中添加了一个道具,即id: Number

    4. 将您的 localStorage 密钥更改为 "item-" + this.id + "-buy""item-" + this.id + "-sell"

    现在每个买卖都将有一个不同的 localStorage 密钥,其 id 不同。

    我强烈推荐使用 Vuex,从长远来看它会让事情变得更容易What is Vuex?

    【讨论】:

    • 非常感谢!这确实是解决方案,就这么简单。对于 Vuex,我认为这也会有所帮助。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 2022-11-07
    • 1970-01-01
    • 1970-01-01
    • 2019-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-11
    相关资源
    最近更新 更多