简体   繁体   中英

In Vue js, how can i assign unique id that doesn't reset when page gets reloaded

I am working on a small project to get into Vue js. It is supposed to be a Habittracker. I currently have a bug, if you reload the page and add new habits, my function that is supposed to change the background does not work properly.

here it shows the bug and here is how my array looks:

0
: 
{id: 0, title: "1", ready: false}

1
: 
{id: 1, title: "123", ready: false}

2
: 
{id: 2, title: "123", ready: false}

3
: 
{id: 0, title: "123", ready: true}

I get why it is not working because I am using a counter to assign the id, which resets to 0 when reloaded.

<div class="q-pa-md" v-for="(habit, index) in habits" :key="habit.id">
    <q-card class="my-card" :id="habit.id" ref="card">
      <q-card-section>
        <q-checkbox
          id="checkbox"
          v-model="habit.ready"
          @click="changeToTransparent(habit)"
        >
        </q-checkbox>
        {{ habit.title }}

        <q-btn-dropdown flat class="more" icon="more_horiz">
          <q-list>
            <q-item clickable v-close-popup @click="deletehabit(index)">
              <q-item-section>
                <q-item-label>Delete</q-item-label>
              </q-item-section>
            </q-item>

            <q-item clickable v-close-popup @click="edithabitbutton(index)">
              <q-item-section>
                <q-item-label>Edit</q-item-label>
              </q-item-section>
            </q-item>
          </q-list>
        </q-btn-dropdown>
      </q-card-section>
    </q-card>
    <div>

let counter = 0;
const habits = ref([]);


const addHabit = () => {
  
  habits.value.push({ id: counter++, title: habittitle.value, ready: false });
  savetolocalstorage();
  habittitle.value = "";
};

const changeToTransparent = (habit) => {

  if(document.getElementById(habit.id) != null) {
    if (habit.ready) {
    document.getElementById(habit.id).style.backgroundColor =
      "rgba(170,193,200,0.25)";
    savetolocalstorage();
  } else {
    document.getElementById(habit.id).style.backgroundColor = "";
    savetolocalstorage();
  }
  }
 
}

Any ideas on how I could fix this?

You need to load your localStorage and set the length to the counter value. I made a working example here. I also improved your code so that it's more in line with Vue's concepts. As @Rahul Purohit pointed out, you will need to JSON.stringify the result when saving and JSON.parse it when loading.

<template>
  <q-input label="Title" v-model="habitTitle" />
  <q-btn label="Add habit" @click="addHabit" />
  <div class="q-pa-md" v-for="(habit, index) in habits" :key="habit.id">
    <q-card
      class="my-card"
      :id="habit.id"
      :ref="(el) => (cardRefs[habit.id] = el)"
    >
      <q-card-section>
        <q-checkbox
          id="checkbox"
          v-model="habit.ready"
          @click="changeToTransparent(habit)"
        >
        </q-checkbox>
        {{ habit.id }} {{ habit.title }}

        <q-btn-dropdown flat class="more" icon="more_horiz">
          <q-list>
            <q-item clickable v-close-popup @click="deletehabit(index)">
              <q-item-section>
                <q-item-label>Delete</q-item-label>
              </q-item-section>
            </q-item>

            <q-item clickable v-close-popup @click="edithabitbutton(index)">
              <q-item-section>
                <q-item-label>Edit</q-item-label>
              </q-item-section>
            </q-item>
          </q-list>
        </q-btn-dropdown>
      </q-card-section>
    </q-card>
  </div>
</template>

<script setup>
const { ref, onMounted } = require("vue");

// it can be just a let.
const counter = ref(0);
const habits = ref([]);
const habitTitle = ref("test");
const cardRefs = ref({});

const saveToLocalStorage = () => console.log("saved");

const addHabit = () => {
  habits.value.push({
    id: counter.value++,
    title: habitTitle.value,
    ready: false,
  });
  saveToLocalStorage();
  habitTitle.value = "";
};

const changeToTransparent = (habit) => {
  if (cardRefs.value[habit.id] != null) {
    if (habit.ready) {
      cardRefs.value[habit.id].$el.style.backgroundColor =
        "rgba(170,193,200,0.25)";
      saveToLocalStorage();
    } else {
      cardRefs.value[habit.id].$el.style.backgroundColor = "";
      saveToLocalStorage();
    }
  }
};

onMounted(() => {
  // Load habits from localStorage
  // This is just an example
  habits.value = [
    {
      id: 0,
      title: "Testing new habit",
      ready: true,
    },
    {
      id: 1,
      title: "Testing new habit",
      ready: false,
    },
    {
      id: 2,
      title: "Testing new habit",
      ready: false,
    },
  ];
  counter.value = habits.value.length;
});
</script>

Ok from the given context, I believe you're not using any backend and are saving all the entries on the local storage.

If that is the case, you must be storing your data in some array to LS like habits: []

Here instead of initiating counter to 0 you can add a lifecycle method.

beforeMount() {
  counter = JSON.parse(localStorage.getItem("habits")).length
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM