Как задать класс элементу списка при клике?

157
29 ноября 2018, 20:00

Есть такой компонент, который отвечает за динамическое отображение списка. Как при клике задать активный класс элементу, по которому кликнули. У меня пока получается, что все <li> получают данный класс.

<template> 
  <div> 
    <li 
      v-for="itemProxy in proxyCountry" :key="itemProxy.id" 
      class="list-group-item" 
      :class="{active: isActive}" 
      @click="viewCurrentProxy(itemProxy.id)" 
      > 
        id-{{ itemProxy.id }}. host: {{itemProxy.host}} 
      </li>   
  </div> 
</template> 
 
<script> 
import { mapGetters } from "vuex"; 
 
export default { 
  name: "listProxyTypeItem", 
  data() { 
    return { 
      isActive: false 
    }; 
  }, 
  created() { 
    this.$store.dispatch("getProxyList"); 
  }, 
  computed: { 
    ...mapGetters(["proxyCountry"]) 
  }, 
  methods: {     
    viewCurrentProxy(id, e) { 
      this.isActive = !this.isActive; 
      this.$store.dispatch("setProxyInfo", id); 
    } 
  } 
}; 
</script> 
 
<style scoped> 
</style>

Answer 1

new Vue({ 
  el: '#app', 
  name: "listProxyTypeItem", 
  data () { 
    return { 
      proxyCountry: [{id: 1, host: 'host 1'}, {id: 2, host: 'host 2'}, {id: 3, host: 'host 3'}, {id: 4, host: 'host 4'}, {id: 5, host: 'host 5'}] 
    }; 
  }, 
  methods: {     
    viewCurrentProxy(id, e) { 
  var options = document.querySelectorAll("li");  
  options.forEach(function(o){ 
   o.className = ""; 
  }); 
  e.target.className = e.target.className =="active"?"":"active"; 
      // this.$store.dispatch("setProxyInfo", itemProxy.id); 
    } 
  } 
 
})
.active { 
  color: green; 
}
<script src="https://unpkg.com/vue"></script> 
 
<div id="app"> 
 
    <li 
      v-for="itemProxy in proxyCountry" :key="itemProxy.id" 
      class="list-group-item" 
       
      @click="viewCurrentProxy(itemProxy.id, $event)" 
      > 
        id-{{ itemProxy.id }}. host: {{itemProxy.host}} 
      </li>   
 
 
</div>

Answer 2

Вы использовали одну переменную на все элементы. У каждого элемента должно быть свое isActive, которое можно легко изменить при клике. В viewCurrentProxy передаете itemProxy(это объект, он передается по ссылке, то есть в параметре у нас точно такой же объект что и отображается) и меняете лично его свойство isActive.

new Vue({ 
  el: '#app', 
  name: "listProxyTypeItem", 
  data () { 
    return { 
      proxyCountry: [{id: 1, host: 'host 1', isActive: false }, {id: 2, host: 'host 2', isActive: false }, {id: 3, host: 'host 3', isActive: false }, {id: 4, host: 'host 4', isActive: false }, {id: 5, host: 'host 5', isActive: false }] 
    }; 
  }, 
  methods: {     
    viewCurrentProxy (itemProxy) { 
      // две строчки ниже если надо чтобы активным был максимум 1 элемент 
      // const active = this.proxyCountry.find(i => i.isActive) 
      // active && (active.isActive = false) 
 
      itemProxy.isActive = !itemProxy.isActive 
      // this.$store.dispatch("setProxyInfo", itemProxy.id); 
    } 
  } 
})
.active { 
  color: blue; 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script> 
 
<div id="app"> 
  <li 
    v-for="itemProxy in proxyCountry"  
    :key="itemProxy.id" 
    :class="{active: itemProxy.isActive, 'list-group-item': true}" 
    @click="viewCurrentProxy(itemProxy)" 
  > 
      id-{{ itemProxy.id }}. host: {{itemProxy.host}} 
    </li>   
</div>

Также обратите внимание, если нужно использовать класс не зависящий от пременной data, который нужен по умолчанию, то не нужно писать два раза class как в Вашем вопросе, нужно вот так: :class="{active: itemProxy.isActive, 'list-group-item': true}"

Answer 3

Не обратил внимание что данные у вас из хранилища. У Вас же isActive не нужно сохранять в бд?

Если Вам надо менять isActive во всем хранилище, то можно сделать так: использовать computed где Вы указали getter и менять состояние state который возвращает этот геттер(то есть у Вас proxyCountry должен возвращать модифицированную переменную из state, эту переменную и надо менять). По идее Ваш dispatch("setProxyInfo", itemProxy.id) и должен менять isActive, не знаю что он у Вас делает. Вы можете переделать setProxyInfo чтобы он принимал id и объект данных которые изменились: dispatch("setProxyInfo", {id: itemProxy.id, changed: {itemProxy.isActive}}). Дальше в этом действии делаете поиск исходя из id, извлекаете нужный элемент, применяете измененные данные через мутацию. Последний шаг могу описать более подробно, но может Вам этот вариант и не нужен.

Есть еще более простой вариант, хранилище при этом не затрагивается, но isActive будет меняться для itemProxy, нужно на этапе created скопировать из геттера в data:

created () {
  this.proxyCountryData = this.proxyCountry
}

И заменить у Вас в коде proxyCountry на proxyCountryData

Если Вам достаточно просто переключать класс, то можете так и оставить.

READ ALSO
TypeError: $.browser is undefined

TypeError: $.browser is undefined

Хочу сделать переход якорю плавнымВот html:

156
По поисковым запросам и релевантности [закрыт]

По поисковым запросам и релевантности [закрыт]

Я ввожу Jahonts в поиск по латвии и мне выводит столбец с отделами сайта, адресом ,верменем работы и телефономKак добится того же на своём сайте...

104
Вывод input name AJAX

Вывод input name AJAX

Нужно вывести в тег заполненное имя форма:

208
Выбор между блоком и элементом в BEM

Выбор между блоком и элементом в BEM

Допустим есть такая структура

145