Добавить класс при клике другому div

224
20 декабря 2018, 17:50

Есть несколько select-oв. Если мы на него кликаем добовляется class="open" нашему списку. Как это можно реализовать на Vue.js. С помощью JQ это получается реализовать:

methods: {
  toggleClass(e) {
    $(e.currentTarget).children('.option_box').toggleClass('open');
}

}

а без него не выходит.

new Vue({ 
  el: "#app", 
  data: { 
    isOpen: false 
  }, 
  methods: { 
  	toggleClass(e) { 
    	this.isOpen = !this.isOpen 
    } 
  } 
})
#app { 
  display: flex; 
} 
.select { 
  margin: 0 10px; 
} 
.input_val { 
  height: 30px; 
  width: 50px; 
  border: 1px solid #777; 
  background: #ccc; 
  cursor: pointer; 
} 
.option_box { 
  width: 50px; 
  text-align: center; 
  border: 1px solid #777; 
  background: #ccc; 
  display: none; 
} 
.option_box.open { 
  display: block; 
} 
ul { 
  list-style-type: none; 
  padding: 0; 
}
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script> 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="app"> 
  <div class="select"  @click="toggleClass"> 
    <div class="input_val"> 
      <input class="input" type="hidden"> 
    </div> 
    <ul :class="{ option_box: true, open: isOpen }"> 
      <li class="option" v-for="n in 3">{{ n }}</li> 
    </ul> 
  </div> 
  <div class="select"  @click="toggleClass"> 
    <div class="input_val"> 
      <input class="input" type="hidden"> 
    </div> 
    <ul :class="{ option_box: true, open: isOpen }"> 
      <li class="option" v-for="n in 5">{{ n }}</li> 
    </ul> 
  </div> 
  <div class="select"  @click="toggleClass"> 
    <div class="input_val"> 
      <input class="input" type="hidden"> 
    </div> 
    <ul :class="{ option_box: true, open: isOpen }"> 
      <li class="option" v-for="n in 6">{{ n }}</li> 
    </ul> 
  </div> 
</div>

Answer 1

jQuery тут явно лишний. Первое что пришло в голову, не очень изящный способ, но работает

new Vue({ 
  el: '#app', 
  methods: { 
    toggleClass(event) { 
      event.target.nextElementSibling.classList.toggle('open'); 
    } 
  } 
});
#app { 
  display: flex; 
} 
.select { 
  margin: 0 10px; 
} 
.input_val { 
  height: 30px; 
  width: 50px; 
  border: 1px solid #777; 
  background: #ccc; 
  cursor: pointer; 
} 
.option_box { 
  width: 50px; 
  text-align: center; 
  border: 1px solid #777; 
  background: #ccc; 
  display: none; 
} 
.option_box.open { 
  display: block; 
} 
ul { 
  list-style-type: none; 
  padding: 0; 
}
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script> 
 
<div id="app"> 
  <div class="select"  @click="toggleClass"> 
    <div class="input_val"> 
      <input class="input" type="hidden"> 
    </div> 
    <ul :class="{ option_box: true }"> 
      <li class="option" v-for="n in 3">{{ n }}</li> 
    </ul> 
  </div> 
  <div class="select"  @click="toggleClass"> 
    <div class="input_val"> 
      <input class="input" type="hidden"> 
    </div> 
    <ul :class="{ option_box: true }"> 
      <li class="option" v-for="n in 5">{{ n }}</li> 
    </ul> 
  </div> 
  <div class="select"  @click="toggleClass"> 
    <div class="input_val"> 
      <input class="input" type="hidden"> 
    </div> 
    <ul :class="{ option_box: true }"> 
      <li class="option" v-for="n in 6">{{ n }}</li> 
    </ul> 
  </div> 
</div>

Answer 2

Не советую так повторяться в хтмл, можно использовать v-for чтобы отображать похожие элементы, в моем варианте этот подход и задействован.

Также обратите что data должно быть функцией.

new Vue({ 
  el: '#app', 
  data: () => ({ 
    options: [ 
      { 
        length: 3, 
        isOpen: false 
      }, 
            { 
        length: 5, 
        isOpen: false 
      }, 
      { 
        length: 6, 
        isOpen: false 
      } 
    ] 
  }), 
  methods: { 
  	toggleClass (option) { 
      console.log(option) 
    	option.isOpen = !option.isOpen 
    } 
  } 
})
#app { 
  display: flex; 
} 
.select { 
  margin: 0 10px; 
} 
.input_val { 
  height: 30px; 
  width: 50px; 
  border: 1px solid #777; 
  background: #ccc; 
  cursor: pointer; 
} 
.option_box { 
  width: 50px; 
  text-align: center; 
  border: 1px solid #777; 
  background: #ccc; 
  display: none; 
} 
.option_box.open { 
  display: block; 
} 
ul { 
  list-style-type: none; 
  padding: 0; 
}
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script> 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="app"> 
  <div  
    v-for="(option, i) in options"  
    :key="i" 
    class="select" 
  > 
    <div class="input_val" @click="toggleClass(option)"> 
      <input class="input" type="hidden"> 
    </div> 
    <ul :class="{ option_box: true, open: option.isOpen }"> 
      <li class="option" v-for="n in option.length">{{ n }}</li> 
    </ul> 
  </div> 
</div>

Answer 3

Передавать индекс параметром в функцию

new Vue({ 
  el: "#app", 
  data: { 
    openData: [{isOpen:false}, {isOpen:false}, {isOpen:false}], 
  }, 
  methods: { 
    toggleClass(i) { 
      this.openData[i].isOpen = !this.openData[i].isOpen; 
    }, 
    isOpen(i) { 
      return this.openData[i].isOpen; 
    } 
  } 
})
#app { 
  display: flex; 
} 
.select { 
  margin: 0 10px; 
} 
.input_val { 
  height: 30px; 
  width: 50px; 
  border: 1px solid #777; 
  background: #ccc; 
  cursor: pointer; 
} 
.option_box { 
  width: 50px; 
  text-align: center; 
  border: 1px solid #777; 
  background: #ccc; 
  display: none; 
} 
.option_box.open { 
  display: block; 
} 
ul { 
  list-style-type: none; 
  padding: 0; 
} 
.open { 
   background: #fff; 
}
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script> 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="app"> 
  <div class="select"  @click="toggleClass(0)"> 
    <div class="input_val"> 
      <input class="input" type="hidden"> 
    </div> 
    <ul :class="{ 'option_box': true, 'open': isOpen(0) }"> 
      <li class="option" v-for="n in 3">{{ n }}</li> 
    </ul> 
  </div> 
  <div class="select"  @click="toggleClass(1)"> 
    <div class="input_val"> 
      <input class="input" type="hidden"> 
    </div> 
    <ul :class="{ 'option_box': true, 'open': isOpen(1) }"> 
      <li class="option" v-for="n in 5">{{ n }}</li> 
    </ul> 
  </div> 
  <div class="select"  @click="toggleClass(2)"> 
    <div class="input_val"> 
      <input class="input" type="hidden"> 
    </div> 
    <ul :class="{ 'option_box': true, 'open': isOpen(2) }"> 
      <li class="option" v-for="n in 6">{{ n }}</li> 
    </ul> 
  </div> 
</div>

READ ALSO
Подскажите утилиту из lodash?

Подскажите утилиту из lodash?

Подскажите утилиту из lodash которая делает следующее

198
как проверить выбор файла в input[file]

как проверить выбор файла в input[file]

нужно что бы когда файл уже выбрали изменялся label, как проверять на выбор файла в js?

172
Написать метод/функцию, который на вход принимает массив городов, выводит их через запятую, в конце ставит точку

Написать метод/функцию, который на вход принимает массив городов, выводит их через запятую, в конце ставит точку

Написать метод/функцию, который на вход принимает массив городов, выводит их через запятую, в конце ставит точкуПример: «Севастополь, Москва,...

260
Поиск DOM элементов сверху

Поиск DOM элементов сверху

У меня есть таблица:

155