admin管理员组文章数量:1313735
Desperately in need of your help guys.
So basically I have a custom checkbox ponent whit a v-model. I use a v-for loop on the ponent to display checkboxes with the names from the array. In the parent ponent I have two columns Available and Selected. The idea is that if I check one of the boxes in the Available column it should appear on the Selected column. The problem is that it displays letter by letter and not the full name.
I am able to achieve the desired result without having a checkbox ponent, but since I will be needing checkboxes a lot throught my project I want to have a ponent for it.
Please follow the link for the code: CodeSandBox
Dont mind the difference in styling.
The problem:
The desired oute:
Desperately in need of your help guys.
So basically I have a custom checkbox ponent whit a v-model. I use a v-for loop on the ponent to display checkboxes with the names from the array. In the parent ponent I have two columns Available and Selected. The idea is that if I check one of the boxes in the Available column it should appear on the Selected column. The problem is that it displays letter by letter and not the full name.
I am able to achieve the desired result without having a checkbox ponent, but since I will be needing checkboxes a lot throught my project I want to have a ponent for it.
Please follow the link for the code: CodeSandBox
Dont mind the difference in styling.
The problem:
The desired oute:
Share Improve this question asked Oct 7, 2021 at 10:22 FersekFersek 371 gold badge1 silver badge10 bronze badges2 Answers
Reset to default 4There are two problems. The first problem is, that you have your v-model
set to v-model="filter.filterCollection"
, so a checkbox you select will be stored into the array as a string and if you select another checkbox the string gets overwritten. The second problem is, that you call that stored string as an array. That causes, that your string, which is an array of letters, will be rendered for each letter. So 'Number' is like ["N", "u", "m", "b", "e", "r"]
.
To solve your problem, you need to store every selection with its own reference in your v-model
. To cover your needs of correct listing and correct deleting you need to apply the following changes:
Your checkbox loop
<Checkbox
v-for="(item, index) in items"
:key="item.id"
:label="item.name"
:id="index"
:isChecked="isChecked(index)" // this is new
@remove-selected-filter="removeSelectedFilter" // This is new
:modelValue="item.name"
v-model="filter.filterCollection[index]" // Change this
/>
Your v-model
filter: {
filterCollection: {} // Object instead of array
}
Methods in FilterPopUp.vue
methods: {
removeSelectedFilter(index) {
delete this.filter.filterCollection[index];
},
isChecked(index) {
return !!this.filter.filterCollection[index];
}
}
Your Checkbox.vue:
<template>
<label>
<p>{{ label }}</p>
<input
type="checkbox"
:id="id"
:value="modelValue"
:checked="isChecked"
@change="emitUncheck($event.target.checked)"
@input="$emit('update:modelValue', $event.target.value)"
/>
<span class="checkmark"></span>
</label>
</template>
<script>
export default {
name: "Checkbox",
props: {
modelValue: { type: String, default: "" },
isChecked: Boolean,
label: { type: String },
value: { type: Array },
id: { type: Number },
},
methods: {
emitUncheck(event) {
if(!event){
this.$emit('remove-selected-filter', this.id);
}
}
}
};
</script>
This should now display your items properly, delete the items properly and unselect the checkboxes after deleting the items.
StevenSiebert has correctly pointed to your errors.
But his solution is not plete, since the filters will not be removed from the collection when you uncheck one of them.
Here is my plete solution of your checkbox working as expected:
Checkbox.vue
<template>
<label>
<p>{{ label }}</p>
<input
type="checkbox"
:id="id"
v-model="checked"
@change="$emit('change', { id: this.id, checked: this.checked})"
/>
<span class="checkmark"></span>
</label>
</template>
<script>
export default {
name: "Checkbox",
props: {
modelValue: { type: Boolean, default: false },
label: { type: String },
id: { type: Number },
},
emits: ["change"],
data() {
return {
checked: this.modelValue
};
}
};
</script>
FilterPopUp.vue
<template>
...
<Checkbox
v-for="(item, index) in items"
:key="index"
:label="item.name"
:id="index"
@change="onChange"
/>
...
</template>
<script>
...
methods: {
removeSelectedFilter(index) {
this.filter.filterCollection.splice(index, 1);
},
onChange(args) {
const {id, checked} = args;
const item = this.items[id].name;
if (checked) {
if (this.filter.filterCollection.indexOf(item) < 0) {
this.filter.filterCollection.push(item);
}
} else {
this.filter.filterCollection = this.filter.filterCollection.filter( i=> i != item);
}
},
},
...
Here is the working CodeSandbox:
https://codesandbox.io/s/pensive-shadow-ygvzb?file=/src/ponents/Checkbox.vue
Sure, there are many ways to do it. If somebody has a nicer and shorter way to do it, please post your solution. It will be interesting to look at it.
本文标签: javascriptVue 3 custom checkbox component with vmodel and array of itemsStack Overflow
版权声明:本文标题:javascript - Vue 3 custom checkbox component with v-model and array of items - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741958481a2407126.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论