выбрать / отменить выбор одного элемента в v-for - PullRequest
1 голос
/ 23 июня 2019

Я пытаюсь создать список опций с помощью v-for, где вы можете выбрать только один вариант за один раз. Он отлично работает, но я не могу отменить выбор.

<div id="main">
  <ul>
    <li 
        v-for="l in list" 
        id="l.key"
        @click="selectone(l.key, l.isSelected)"
        v-bind:class="{ selected : l.isSelected, notselected : !l.isSelected }"
        > {{ l.tec }} </li>
   <ul>
</div>

JS

new Vue({
  el:"#main",
  data: {
    list: [
      {key:"0", tec:"html", isSelected:false},
      {key:"1", tec:"css", isSelected:false},
      {key:"2", tec:"JS", isSelected:false},
      {key:"3", tec:"Git", isSelected:false},
      {key:"4", tec:"NodeJS", isSelected:false},
      {key:"5", tec:"Postgres", isSelected:false}
    ]
  },
  methods: {
    selectone: function(k, o) {
      for( i = 0; i < this.list.length; i ++ ) {
        if(this.list[i].isSelected == true ) {
          this.list[i].isSelected = false
        }
      }
      this.list[k].isSelected = !this.list[k].isSelected;
    }
  }
})

CSS

.selected {
    background:lightpink;
}
.notselected {
    background:lightblue;
}

Не должен ли мой цикл деактивировать все параметры каждый раз, когда я щелкаю элемент?

Ответы [ 2 ]

2 голосов
/ 23 июня 2019

Твои близкие.попробуйте это: (не проверено)

<div id="main">
  <ul>
    <li 
        v-for="(l,index) in list" 
        id="l.key"
        @click="selectone(l, index)"
        v-bind:class="{ selected : l.isSelected, notselected : !l.isSelected }"
        > {{ l.tec }} </li>
   <ul>
</div>

JS

new Vue({
  el:"#main",
  data: {
    list: [
      {key:"0", tec:"html", isSelected:false},
      {key:"1", tec:"css", isSelected:false},
      {key:"2", tec:"JS", isSelected:false},
      {key:"3", tec:"Git", isSelected:false},
      {key:"4", tec:"NodeJS", isSelected:false},
      {key:"5", tec:"Postgres", isSelected:false}
    ]
  },
  methods: {
    selectone:function(l, index){

      for( i = 0; i < this.list.length; i ++ ) {
        this.list[i].isSelected = false
        }
      l.isSelected = true;
      }
    }
  }
})

, чтобы объяснить, что вы пропустили использование переменной k в вашей функции.это должен быть весь объект, а не индекс

1 голос
/ 23 июня 2019

В selectone() вы устанавливаете isSelected=false для всех элементов списка, а затем пытается переключить выбранный элемент списка isSelected, который был только что установлен ранее на false (т. е. «переключатель» всегда будет устанавливать isSelected=true для выбранного элемента).

Цикл должен исключать ключ выбранного элемента:

selectone(key) {
  for (let i = 0; i < this.list.length; i++) {
    if (this.list[i].key !== key) {
       this.list[i].isSelected = false
    }
  }

  // this.toggleSelection(key)
}

Но сам по себе переключающий код нуждается в исправлении ошибки, чтобы правильно искать элемент списка. Первый аргумент selectone() является свойством key элемента списка. Чтобы получить элемент по ключу из массива list, необходимо выполнить поиск по list, например, используя Array.prototype.find():

toggleSelection(key) {
  const listItem = this.list.find(item => item.key === key)
  if (listItem) {
    listItem.isSelected = !listItem.isSelected
  }
}

new Vue({
  el: '#app',
  data: {
    list: [
      {key:"0", tec:"html", isSelected:false},
      {key:"1", tec:"css", isSelected:false},
      {key:"2", tec:"JS", isSelected:false},
      {key:"3", tec:"Git", isSelected:false},
      {key:"4", tec:"NodeJS", isSelected:false},
      {key:"5", tec:"Postgres", isSelected:false}
    ]
  },
  methods: {
    selectone(key) {
      for (let i = 0; i < this.list.length; i++) {
        if (this.list[i].key !== key) {
          this.list[i].isSelected = false
        }
      }

      this.toggleSelection(key)
    },
    toggleSelection(key) {
      const listItem = this.list.find(item => item.key === key)
      if (listItem) {
        listItem.isSelected = !listItem.isSelected
      }
    }
  }
})
.selected {
  background:lightpink;
}
.notselected {
  background:lightblue;
}
<script src="https://unpkg.com/vue@2.6.10"></script>

<div id="app">
  <ul>
    <li 
        v-for="l in list" 
        id="l.key"
        @click="selectone(l.key, l.isSelected)"
        v-bind:class="{ selected : l.isSelected, notselected : !l.isSelected }"
        > {{ l.tec }} </li>
   <ul>
</div>

Кроме того, вы можете отслеживать выбранный индекс, устанавливать его в обработчике click элемента и устанавливать привязку class на основе индекса элемента, соответствующего выбранному индексу:

// template
<li 
  v-for="(l, index) in list" 
  id="l.key"
  @click="selectedIndex = index"
  v-bind:class="{ selected: index === selectedIndex, notselected: index !== selectedIndex }"
  > {{ l.tec }} </li>

// script
export default {
  data() {
    return {
      selectedIndex: -1,
      ...
    }
  }
}

new Vue({
  el: '#app',
  data: {
    selectedIndex: -1,
    list: [
      {key:"0", tec:"html", isSelected:false},
      {key:"1", tec:"css", isSelected:false},
      {key:"2", tec:"JS", isSelected:false},
      {key:"3", tec:"Git", isSelected:false},
      {key:"4", tec:"NodeJS", isSelected:false},
      {key:"5", tec:"Postgres", isSelected:false}
    ]
  }
})
.selected {
  background:lightpink;
}
.notselected {
  background:lightblue;
}
<script src="https://unpkg.com/vue@2.6.10"></script>

<div id="app">
  <ul>
    <li 
        v-for="(l, index) in list" 
        id="l.key"
        @click="selectedIndex = index"
        v-bind:class="{ selected : index === selectedIndex, notselected : index !== selectedIndex }"
        > {{ l.tec }} </li>
   <ul>
</div>
...