Не удается динамически добавить класс в Vue. js - PullRequest
1 голос
/ 12 апреля 2020

Перепробовал все варианты этого. Использовал официальные Vue руководства , а также другие сообщения о переполнении стека и различные учебные пособия. Я пробовал с и без кавычек, я пробовал синтаксис массива, я пробовал почти все. По какой-то причине, хотя я могу успешно переключать свойство data, мой класс css не применяется к элементам, когда isLearned - true.

Вот мой HTML:

<li 
    v-for="(flashcard, index) in flashcards"
    v-bind:class="{learned: isLearned, flashcard}"
    @click="toggleSide(flashcard)">
    <p>{{flashcard.isFlipped ? flashcard.phrase : flashcard.definition}}</p>
    <button @click="learnedCard(flashcard, index)">Learned</button>
</li>

Вот мой JS:

new Vue({
  el: "#esl-flashcards",
  data: {
    flashcards: flashcards,
    inputPhrase: '',
    inputDef: '',
    isLearned: false,
  },
  methods: {
    learnedCard: function(flashcard, index) {
      for (let i = 0; i < flashcards.length; i += 1){
        if (i === index) {
          flashcards[i].isLearned = !flashcards[i].isLearned;
        }
      };
    },
  },
});

1 Ответ

0 голосов
/ 12 апреля 2020

Немного проблем здесь:

isLearned фактически является свойством каждого flashcard объекта. Итак, когда вы делаете:

flashcards[i].isLearned = !flashcards[i].isLearned;

, вы на самом деле обновляете это свойство, но вы проверяете stati c data isLearned изменение свойства в классе, как

v-bind:class="{learned: isLearned, flashcard}"

Таким образом, вы не видите никакого изменения класса вообще. Вам просто нужно вызвать его как:

v-bind:class="{learned: flashcard.isLearned, flashcard}"

Также здесь:

for (let i = 0; i < flashcards.length; i += 1){
    if (i === index) {
      flashcards[i].isLearned = !flashcards[i].isLearned;
    }
};

Вы звоните напрямую flashcards, который всегда будет неопределенным в v ie , Вы должны назвать это как this.flashcards. Но так как вы уже передаете индекс массива методу learnedCard(), вам не нужно l oop здесь. Вы можете просто использовать метод .find() для достижения того же результата в несколько строк, например:

 learnedCard: function(flashcard, index) {
      var card = this.flashcards.find((f,i) => i===index)
      card.isLearned = !card.isLearned;
 },

Рабочая демонстрация:

new Vue({
  el: "#esl-flashcards",
  data: {
    flashcards: Array.from({length:4}, (_, i) => ({text: `Item ${i+1}`, isLearned: false})),
    inputPhrase: '',
    inputDef: '',
    isLearned: false,
  },
  methods: {
    learnedCard: function(flashcard, index) {
      var card = this.flashcards.find((f,i) => i===index)
      card.isLearned = !card.isLearned;
    },
  },
});
li.learned {background-color:skyblue;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="esl-flashcards">
  <ul>
    <li v-for="(flashcard, index) in flashcards" v-bind:class="{learned: flashcard.isLearned, flashcard}">
      <p>{{flashcard.text}}</p>
      <button @click="learnedCard(flashcard, index)">Learned</button>
    </li>
  </ul>
</div>
...