cgobbet
cgobbet

Reputation: 319

Adding persistence to local storage to a Vue app

I am learning to deal with VueJS and made a simple todo app. It works well, but I want to store data locally and make it persistent even if there is a page reload.

This is the code produced following instruction of a few useful tutorials (leaving CSS outside to ease readability):

<template>
  <div class="main-container">
    <div class="header md-elevation-4">
      <h1 class="md-title">{{ header }}</h1>
    </div>
    <div class="todo-list">
      <div class="row"></div>
      <div class="row">
        <!-- add new todo with enter key -->
        <md-field class="todo-input">
          <md-input
            v-model="currentTodo"
            @keydown.enter="addTodo()"
            placeholder="Add a todo! It's easy!"
          />
        </md-field>
        <!-- for all todos, set class of edited todos -->
        <ul class="todos">
          <div class="list-div">
            <li v-for="todo in todos" :key="todo.id">
              <!-- binds checkbox to todo model after each instance; -->
              <input
                class="toggle-todo"
                type="checkbox"
                v-model="todo.completed"
              />
              <!-- starts editing process on double click -->
              <span
                class="todo-item-label"
                :class="{ completed: todo.completed }"
                @dblclick="editTodo(todo)"
                v-if="!todo.edit"
                >{{ todo.label }}</span
              >
              <!-- concludes editing with enter click -->
              <input
                v-else
                class="todo-item-edit"
                type="text"
                v-model="todo.label"
                @keyup.enter="completedEdit(todo)"
              />
              <!-- deletes todos using removeTodo method -->
              <i
                class="material-icons"
                alt="remove toDo"
                @click="removeTodo(todo)"
                >delete</i
              >
            </li>
          </div>
        </ul>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "RegularToolbar",
  data() {
    return {
      header: "A VueJS ToDo App",
      todos: [],
      currentTodo: "",
      completed: false, // add a completed property
      editedToDo: null // add a edited property
    };
  },
  methods: {
    addTodo() {
      this.todos.push({
        id: this.todos.length,
        label: this.currentTodo,
        completed: false, // initializes property
        edit: false // initializes property
      });
      this.currentTodo = "";
    },
    mounted() {
      // console.log('App mounted!');
      if (localStorage.getItem("todos"))
        this.todos = JSON.parse(localStorage.getItem("todos"));
    },
    watch: {
      todos: {
        handler() {
          // console.log('Todos changed!');
          localStorage.setItem("todos", JSON.stringify(this.todos));
        },
        deep: true
      }
    },
    removeTodo(todo) {
      // allows users to remove todos
      var index = this.todos.indexOf(todo);
      this.todos.splice(index, 1);
    },
    editTodo(todo) {
      todo.edit = true;
    },
    completedEdit(todo) {
      todo.edit = false;
    }
  }
};
</script>

<style lang="scss" scoped></style>

As it is, all the JS part referring to mount and watch does not work. I am able to add new todos and delete them as I wish, but it does not retain the data if the user reloads the page.

Could some of the colleagues spot what I am missing here?

Upvotes: 1

Views: 1027

Answers (1)

ebbishop
ebbishop

Reputation: 1983

It's a problem of code organization:

Your mounted and watch sections are currently inside the methods section, which will prevent them from firing as expected.

Move those out into their own sections (both should be at the same level as methods) and you should be all set.

With those edits and nothing else, I've got your code working in a fiddle here: https://jsfiddle.net/ebbishop/dc82unyb/

Upvotes: 2

Related Questions