@EvgeniyR1987

Как сделать отмеченную форму checkbox устойчивой к обновлению страницы в браузере на Vue.js?

У меня есть приложение ToDo List на Vue. С помощью кнопки добавить запись, добавляется новая строка текста, каждая из которых имеет чекбокс и кнопку удалить. Моя задача: сохранять все введенные данные из форм (текст и выбран или нет чекбокс) при обновлении страницы браузера. Для этого использую mounted и watch, но получается только сохранять данные текста, чекбоксы так и не нашел пока как сохранить (неудачные попытки в коде не выкладывал).

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>To Do List</title>
</head>
<link rel="stylesheet" href="style.css">
<style>
    [v-cloak] {
        display:none;
    }
</style>
<body>
    <div class="container" id="app" v-cloak>
      <div class="card">
          <h1>To Do List</h1>
          <div class="form-control">
             <input
                 type="text" 
                 v-bind:placeholder="placeholder" 
                 v-model="inputvalue"
                 v-on:keypress.enter="addnewtask"
              />
              <button class="btn" v-on:click="addnewtask">Add Task</button>
            </div>
            <hr />
            <ul class="list" v-if="notes.length !== 0">
                <li class="list-item" v-for="(note, index) in notes" v-bind:key="note">
                    <div>
                        <input type="checkbox" v-model="checked[note]"/>
                        <span :style="checked[note] ? 'text-decoration: line-through' : ''">
                            {{index+1}}) {{note}}
                        </span>
                    </div>
                    <button class="btn danger" v-on:click="removetask(index)">Delete</button>
                </li>
                <hr />
                <li>
                    <strong>Total: {{notes.length}}</strong>
                </li>
            </ul>
            <div v-else>No task exist, please add first one.</div>
      </div>
    </div>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="Vue3.js"></script>
</body>
</html>

Vue.createApp({
    data(){
        return{
          placeholder: 'Start typing',
          inputvalue: '',
          notes: [],
          checked: []
        }
    },
    mounted() {
        this.notes = JSON.parse(localStorage.getItem('note')) || [];
      },
    watch: {
            notes: {
                handler: function() {
                localStorage.setItem('note', JSON.stringify(this.notes));
                },
                deep: true
            }
    },
    methods: {
        addnewtask(){
            if (this.inputvalue !== ''){
                this.notes.push(this.inputvalue)
                this.inputvalue=''
            }
        },
        removetask(index){
            if (confirm('Do you really want to delete?'))
            this.notes.splice(index, 1)
        }
    }
}).mount(app)
  • Вопрос задан
  • 479 просмотров
Решения вопроса 1
0xD34F
@0xD34F Куратор тега Vue.js
Зачем отдельный массив checked? Пусть notes вместо массива строк будет массивом объектов, состоящих из двух свойств - text и checked. Наблюдатель c deep: true, сохраняющий данные в localStorage уже есть, так что никаких дополнительных действий предпринимать не придётся.

UPD. Как это может выглядеть:

<div id="app">
  <div>
    <input v-model="newTaskText" @keypress.enter="addTask">
    <button @click="addTask">add</button>
  </div>
  <hr>
  <ol v-if="tasks.length">
    <li v-for="(n, i) in tasks">
      <label :class="{ 'task-checked': n.checked }">
        <input type="checkbox" v-model="n.checked">
        {{ n.text }}
      </label>
      <button @click="delTask(i)">del</button>
    </li>
  </ol>
  <strong>Total: {{ tasks.length || 'no tasks fucking exist' }}</strong>
</div>

.task-checked {
  text-decoration: line-through;
}

Vue.createApp({
  data: () => ({
    newTaskText: '',
    tasks: JSON.parse(localStorage.getItem('tasks')) ?? [],
  }),
  watch: {
    tasks: {
      deep: true,
      handler: val => localStorage.setItem('tasks', JSON.stringify(val)),
    },
  },
  methods: {
    addTask() {
      const text = this.newTaskText.trim();
      if (text) {
        this.tasks.push({
          text,
          checked: false,
        });

        this.newTaskText = '';
      } else {
        alert('fuck off');
      }
    },
    delTask(index) {
      if (confirm('really?')) {
        this.tasks.splice(index, 1);
      }
    },
  },
}).mount('#app');
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы