Почему сразу все чек-боксы отмечаются активными Vue.js?
Начал изучать Vue.js и столкнулся вот с такой проблемой. У меня есть компонент MyCheckbox, в котором просто кастомный чек бокс. Собственно ближе к делу, что у меня странно работает. Когда я нажимаю на один чекбокс срабатывают сразу все.
#parent.vue
<script setup>
import {ref} from "vue";
import CheckBox from "@/components/CheckBox.vue";
let count = ref(0);
let checked = ref(['Jack']);
function increment() {
count.value++
}
</script>
<template>
<h1>{{ checked }}</h1>
<CheckBox name="Some_name1" v-model="checked" id="A"/>
<CheckBox v-model="checked" name="Some_name2" id="v"/>
<CheckBox v-model="checked" name="Some_name3" id="b"/>
<CheckBox v-model="checked" name="Some_name4" id="a"/>
</template>
Мне нужно, чтобы через v-model, имя чекбокса добавлялось в список checked (без компонентного чекбокса это работает без всяких проблем).
#CheckBox.vue
<script setup>
defineProps({
name: String,
id: String
})
const model = defineModel()
function printName() {
console.log(model)
}
</script>
<template>
<input type="checkbox" class="checkbox" id={{id}} value={{name}} v-model="model" @click="printName">
<label>Hello</label>
</template>
<style scoped>некоторые стили</style>
Во-первых, нажимая на один чекбокс, имя, которое добавляется в список имеет такой вид: "{{name}}". И во-вторых уже выше упомянутая проблема, что все чекбоксы отмечаются одновременно вместе
Ответы (1 шт):
Во-первых: неправильное использование переменных в шаблоне вашего кода.ы использовали {{name}}
в атрибутах, это было буквальным строковым значением, а не переменной.
<input type="checkbox" class="checkbox" :id="id" :value="name" v-model="model" @click="printName">
Во-вторых: обратите внимание как вы используете v-model
в вашем компоненте и как передаёте данные между родительским и дочерним компонентами. Когда вы используете v-model
с массивом в родителе и одновременно привязываете его ко всем чекбоксам, это интерпретируется так, что все чекбоксы управляют одним и тем же состоянием. Поэтому, изменяя состояние одного чекбокса, вы меняете состояние всех чекбоксов, связанных с этим массивом.
v-model
из parent.vue
связан с массивом и его обновление происходит через событие update:modelValue
, которое обрабатывается в дочернем компоненте: ваш пример на https://play.vuejs.org/
#CheckBox.vue
<script setup>
import { defineProps, defineEmits } from "vue";
const props = defineProps({
modelValue: Array, // массив для v-model
name: String,
id: String
});
const emit = defineEmits(['update:modelValue']);
function toggleCheck(event) {
const newValue = event.target.checked
// Если чекбокс отмечен, добавляем его имя в массив modelValue
? [...props.modelValue, props.name]
// Если чекбокс снят, удаляем его имя из массива modelValue
: props.modelValue.filter(item => item !== props.name);
emit('update:modelValue', newValue); // Обновляем modelValue
}
</script>
<template>
<input type="checkbox" :id="id" :value="name" :checked="modelValue.includes(name)" @change="toggleCheck">
<label :for="id">{{name}}</label>
</template>
ПС:
Для чекбокса используется событие
change
вместоclick
, потому что это более логично для обработки изменений его состояния.В шаблоне используется
:checked="modelValue.includes(name)"
для
определения, должен ли чекбокс быть отмеченным, основываясь на
текущем состоянииmodelValue
.