Почему мои флажки сняты при нажатии на другой? (Vue, CSS)


Почему мои флажки сняты при нажатии на другой? (Vue, CSS)

21.11.2020 02:00:59 Просмотров 7 Источник

Я изучаю Vue и ставлю перед собой задачу создать список дел. Чтобы сделать его красивее, я хотел стилизовать свои флажки и использовал эту ссылку в качестве основы.

Это работает в основном нормально: я могу нажать на отмененные задачи, чтобы сделать их выполненными, и наоборот. Однако, если я нажимаю на выполненную задачу, следующая выполненная задача (если она есть) получает стиль отмененной задачи (при правильном пребывании в отделе done). Это выглядит так:

enter image description here

Я не могу понять, почему это происходит. А ты можешь? Спасибо за любую помощь!

Вот мой код:

<template>
  <div style="margin: 10px">
    <input class="newTaskInput" type="text" v-model="newTask" placeholder="Neue Aufgabe">
    <button class="newTaskButton" v-on:click="addTask()">Hinzufügen</button>

    <h3>Offene Aufgaben</h3>
    <div class="taskBox">

      <label class="checkbox-container" v-for="t in unDoneTasks" :key="t.task">
        {{t.task}}
        <input type="checkbox" @click="change_task_state(t)">
        <span class="checkmark"></span>
      </label>

      <span v-if="unDoneTasks.length == 0">Alle Aufgaben erledigt!</span>
    </div>

    <h3>Abgeschlossene Aufgaben</h3>
    <div class="taskBox">

      <label class="checkbox-container" v-for="(t, index) in doneTasks" :key="index">
        <span class="done">{{t.task}}</span>
        <input type="checkbox" checked @click="change_task_state(t)">
        <span class="checkmark"></span>
      </label>

      <span v-if="doneTasks.length == 0">Noch nix erledigt!</span>
    </div>

  </div>
</template>

<script>
export default {
  data() {
    return {
      tasks: [
        { task: 'Milch kaufen', isDone: false },
        { task: 'Aufräumen', isDone: false },
        { task: 'Essen kochen', isDone: false },
        { task: 'Fahrrad reparieren', isDone: true },
      ],
      newTask: '',
    };
  },
  methods: {
    change_task_state(e) {
      e.isDone = !e.isDone;
    },
    addTask() {
      this.tasks.push({ task: this.newTask, isDone: false });
      this.newTask = '';
    },
  },
  computed: {
    unDoneTasks() {
      return this.tasks.filter((t) => !t.isDone);
    },
    doneTasks() {
      return this.tasks.filter((t) => t.isDone);
    },
  },
};
</script>

<style lang="scss">
/* CHECKBOX STYLING */
// Customize the label (the checkbox-container)
.checkbox-container {
  display: block;
  position: relative;
  padding-left: 35px;
  margin-bottom: 12px;
  cursor: pointer;
  font-size: 16px;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

// Hide the browser's default checkbox
.checkbox-container input {
  position: absolute;
  opacity: 0;
  cursor: pointer;
  height: 0;
  width: 0;
}

// Create a custom checkbox
.checkmark {
  position: absolute;
  top: 0;
  left: 0;
  height: 19px;
  width: 19px;
  background-color: #eee;
}

// On mouse-hover
.checkbox-container:hover input ~ .checkmark {
  background-color: coral;
}
.checkbox-container:hover input ~ .checkmark:after {
  display: block;
}

// When the checkbox is checked
.checkbox-container input:checked ~ .checkmark {
  background-color: lightgrey;
}
.checkbox-container input:checked ~ .checkmark:after {
  display: block;
}

// Create the checkmark/indicator (hidden when not checked)
.checkmark:after {
  content: "";
  position: absolute;
  display: none;
}

// Style the checkmark/indicator
.checkbox-container .checkmark:after {
  left: 6px;
  top: 2px;
  width: 5px;
  height: 10px;
  border: solid white;
  border-width: 0 3px 3px 0;
  -webkit-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  transform: rotate(45deg);
}
/* Checkbox end */

.done {
  color: lightgrey;
}
.taskBox {
  max-height: 500px;
  overflow: auto;
}

.newTaskInput {
  margin-top: 8px;
  margin-right: 3px;
  padding: 12px 20px;
  border: none;
  background-color: lightgrey;
  border-radius: 3px;
}
::placeholder {
  color: black;
}
.newTaskButton {
  padding: 12px 20px;
  background-color: coral;
  border-radius: 3px;
  border: coral 3px;
  color: white;
}
</style>
У вопроса есть решение - Посмотреть?

Ответы - Почему мои флажки сняты при нажатии на другой? (Vue, CSS) / Why are my checkboxes unchecked when clicking on another? (Vue, CSS)

Является ответом!
Decade Moon

21.11.2020 02:56:40

Вас укусила комбинация факторов:

  1. Вы неправильно вводите элементы. Манипулирование индексом в списке не позволяет однозначно идентифицировать этот элемент, поскольку индексы элементов будут меняться при перемещении.
  2. Атрибут checked определяет только начальное проверенное состояние флажка. Добавление или удаление этого атрибута не влияет на флажок после того, как он уже создан.

Алгоритм исправления DOM Vue пытается повторно использовать существующие узлы DOM, когда это возможно. При перемещении элементов Vue добавит или удалит атрибут checked из флажка в новом индексе, что не изменит проверенное состояние флажка.

Есть 2 способа исправить это:

  1. (Рекомендуется) используйте ключ, который всегда однозначно идентифицирует данный элемент, даже когда он перемещается по списку. Индекс v-for не будет работать, потому что индекс изменится. Делая это, Vue сохранит <input>, соответствующий этому элементу, тем самым сохраняя его проверенное состояние.

    По какой-то преднамеренной причине Vue не позволяет использовать экземпляр объекта в качестве ключа, что было бы идеально в этой ситуации, поэтому вам придется поддерживать ключ для каждого элемента вручную; Symbol будет работать.

    <label class="checkbox-container" v-for="t in unDoneTasks" :key="t.key">
                                                                     ^^^^^
    
    { key: Symbol(), task: 'Buy milk', isDone: false }
      ^^^^^^^^^^^^^
    
  2. Заставьте Vue установить свойство checked DOM вместо атрибута.

    <!-- Unchecked -->
    <input type="checkbox" :checked.prop="false" @click="change_task_state(t)">
    
    <!-- Checked -->
    <input type="checkbox" :checked.prop="true" @click="change_task_state(t)">
    

    Обратите внимание на разницу между атрибутом checked и свойством checked:

    checked2
Помочь в развитии проекта:
Закрыть X