Активная кнопка фильтрации по тегу! Vue.js
Не могу понять как реализовать подсвечивание выбранную кнопку, которая будет делать фильтрацию по списку - тег! Ранее я использовал моковые данные прям в компоненте, и тогда у меня было поле active: true, ну и я менял состояние все прекрасно.
Но сейчас с API получаю список тегов, и из state забираю список в котором есть поля: name, id.
И как же теперь привязыватся к конкретному элементу не пойму(((
<div v-for="item in tagsList" :key="item.id" class="swiper-slide">
<AppButton
blog-tag-btn
class="swiper-slide-btn"
:blog-tag-btn-active="isActive"
@click="selectTag(item.id)"
>
{{ item.name }}
</AppButton>
</div>
data() {
return {
slider: null,
isActive: false,
}
},
methods: {
selectTag(id) {
this.isActive = !this.isActive
this.$emit('select-tag', id)
},
},
если я сделаю вот так, то будут подсвечивался сразу все кнопки из моего списка, а не конкретная! В этом примере локальная переменная не спасет, а вот нужно какое-то условие, которое будет учитывать уникальность каждой кнопки, а уникальность эту дает id, я когда так уже делал, но вот совсем как обило(
Ответы (1 шт):
new Vue({
el: '#app',
data() { return {
tagsList: [],
isActive: {},
}},
methods: {
selectTag(id) {
this.$set(this.isActive, id, !this.isActive[id]);
this.$emit('select-tag', id);
},
fetchItems() {
fetch('https://jsonplaceholder.typicode.com/users')
.then(r => r.json()).then(data => this.tagsList = data);
},
},
mounted() {
this.fetchItems();
},
});
.swiper-slide { display: inline-block; margin: 0.25rem; }
.swiper-slide-btn { padding: 0.25rem 0.5rem; }
.swiper-slide-btn.active { background: #acf; }
<div id="app">
<div v-for="item in tagsList" :key="item.id" class="swiper-slide">
<button class="swiper-slide-btn"
:class="{ active: isActive[item.id] }"
@click="selectTag(item.id)"
>
{{ item.name }}
</button>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
На что тут следует обратить внимание:
isActive: {},
Это свойство должно содержать структуру, а не одиночное булевое значение - ведь переключаемый элемент у нас не один, их несколько. Обычный объект для такой задачи вполне хорошо подходит.this.$set(this.isActive, id, !this.isActive[id]);
Присваивание нового состояния флага выполняется через метод$set, потому что Vue не имеет возможности автоматически отслеживать добавление новых свойств в объекты.
Если просто присваиватьthis.isActive[id] = !this.isActive[id], то реактивных обновлений не будет, ведь изначально объектisActiveпуст, и Vue "не увидит" в нем появлений новых свойств[id].:class="{ active: isActive[item.id] }"
Бинд класса здесь имеет очень простую логику - классactive(через который кнопки и стилизуются) добавляется элементу когдаisActive[item.id]принимает значениеtrue.
А что при значенииundefined, когда кнопка еще не переключалась? Тоже просто: здесь Vue автоматически приводитundefinedк булевомуfalse, и соотв., класс не добавляется - именно то, что нужно.