#javascript #vue.js
Вопрос:
У меня есть несколько li
элементов в v-for
цикле. Мне нужно выбрать несколько одновременно и, если они уже выбраны, удалить active
класс.
Мой скрипт работает, если я выбираю элементы по порядку: от первого до последнего (для выбора элементов), от последнего до первого (для отмены выбора элементов). Пожалуйста, помогите мне.
var example1 = new Vue({
el: '#example-1',
data: {
tags: ['tag-1', 'tag-2', 'tag-3', 'tag-4'],
activeTag: [],
},
methods: {
onTagClick: function(i) {
if ( this.activeTag.includes(i) ) {
console.log('Delete');
const index = this.activeTag.indexOf(i);
if ( index > -1 ) {
this.activeTag.splice(index, 1);
}
} else {
console.log('Add');
this.activeTag.push(i);
}
console.log(`activeTag[i]: ${this.activeTag}`);
}
}
})
li {
display: inline-block;
padding: 8px 10px;
margin-right: 0.5rem;
}
a {
color: #000;
text-decoration: none;
}
li.active>a{
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.js"></script>
<div id="example-1">
<ul v-if="tags">
<li v-for="(tag, i) in tags" :key="i" :class="{active: activeTag[i] === i}">
<a @click="onTagClick(i)" href="javascript:void(0)">{{ tag }}</a>
</li>
</ul>
</div>
Комментарии:
1. Привет, мой ответ как-то помог ?
2. Привет @kissu, я использовал код Виниция и ваш совет для сопоставления массива. Большое спасибо
Ответ №1:
Что вы думаете об этом решении? Это самый короткий путь к достижению того же результата.
var example1 = new Vue({
el: '#example-1',
data: {
tags: [{tag:'tag-1', active: false},{tag:'tag-2', active: false}, {tag:'tag-3', active: false}, {tag:'tag-4', active: false} ],
},
methods: {
onTagClick: function(i) {
this.tags[i].active = !this.tags[i].active ;
}
}
})
li {
display: inline-block;
padding: 8px 10px;
margin-right: 0.5rem;
}
a {
color: #000;
text-decoration: none;
}
li.active>a{
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.js"></script>
<div id="example-1">
<ul v-if="tags">
<li v-for="(obj, i) in tags" :key="i" :class="{active: obj.active}" >
<a @click="onTagClick(i)" href="javascript:void(0)">{{ obj.tag }}</a>
</li>
</ul>
Ответ №2:
шаблон
<li v-for="(tag, index) in tags" :key="index" :class="{active: tag.active}">
<a href="#" @click.prevent="tag.active = !tag.active">{{ tag.name }}</a>
</li>
Скрипт
computed: {
checked(){ return this.tags.filter(tag => tag.active).map(tag => tag.name)}
},
data() {
return {
tags: [
{name:'tag-1', active: false},
{name:'tag-2', active: false},
{name:'tag-3', active: false},
{name:'tag-4', active: false}
]
}
}
Полный образец. Зацени это
<template>
<ul v-if="tags">
<li v-for="(tag, index) in tags" :key="index" :class="{active: tag.active}">
<a href="#" @click.prevent="tag.active = !tag.active">{{ tag.name }}</a>
</li>
</ul>
<div>
{{checked}}
</div>
</template>
<script>
import { defineComponent } from "vue";
export default defineComponent({
computed: {
checked(){ return this.tags.filter(tag => tag.active).map(tag => tag.name)}
},
data() {
return {
tags: [
{name:'tag-1', active: false},
{name:'tag-2', active: false},
{name:'tag-3', active: false},
{name:'tag-4', active: false}
]
}
}
});
</script>
<style>
li {
display: inline-block;
padding: 8px 10px;
margin-right: 0.5rem;
}
a {
color: #000;
text-decoration: none;
}
li.active>a{
color: red;
}
</style>
Комментарии:
1. Я не могу изменить структуру данных
2. @riky1 почему вы не можете изменить структуру данных ? Я не вижу никакой причины, по которой это невозможно.
3. Я получаю данные из базы данных, и они у меня есть
props
. Я ввел значенияdata()
только для примера4. Вы можете полностью получить эти значения из базы данных и помассировать ее. Проверьте мой обновленный ответ. Реквизиты или данные не имеют никакого значения, это все равно данные, которые вы можете изменить в своем компоненте, не так уж и важно.
Ответ №3:
Вот мое решение
<template>
<div>
<span
v-for="element in array"
:key="element.id"
:class="{ red: element.active }"
@click="toggleSelection(element)"
>
{{ element.label }}
</span>
</div>
</template>
<script>
export default {
data() {
return {
array: [
{ id: 1, label: 'tag1', active: false },
{ id: 2, label: 'tag2', active: false },
{ id: 3, label: 'tag3', active: false },
],
}
},
methods: {
toggleSelection(element) {
const selectedElementIndex = this.array.findIndex((item) => item.id === element.id)
this.array[selectedElementIndex].active = !this.array[selectedElementIndex].active
},
},
}
</script>
<style scoped>
.red {
color: red;
}
</style>
Я по-прежнему настоятельно рекомендую обновить ваш массив и присвоить ему реальный уникальный идентификатор, а не передавать index
:key
его , что на самом деле делает противоположное тому, что он должен делать.
Чтобы создать удобный массив с хорошими ключами, вы можете использовать его на своем текущем tags
:
this.array = tags.map((tag, index) => ({id: index, label: tag, active: false}))
Вы можете вызвать этот метод, как только вы извлекли данные из API (в async created()
хук), изменили их, а затем вставили в свой шаблон, следовательно, изменили структуру в более удобный формат.