具有 v-model 和项目数组的 Vue 3 自定义复选框组件
Posted
技术标签:
【中文标题】具有 v-model 和项目数组的 Vue 3 自定义复选框组件【英文标题】:Vue 3 custom checkbox component with v-model and array of items 【发布时间】:2021-11-27 10:41:30 【问题描述】:迫切需要你们的帮助。
所以基本上我有一个 带有 v-model 的自定义复选框组件。我在组件上使用 v-for 循环来显示带有数组名称的复选框。在父组件中,我有两列可用和选定。这个想法是,如果我选中 Available 列 中的一个框,它应该会出现在 Selected column 上。问题是它按字母显示而不是全名。
我能够在没有复选框组件的情况下实现所需的结果,但由于在我的项目中我将需要很多复选框,因此我希望有一个组件。
请点击以下链接获取代码: CodeSandBox
不要介意样式的差异。
问题:
期望的结果:
【问题讨论】:
【参考方案1】:有两个问题。第一个问题是,您将v-model
设置为v-model="filter.filterCollection"
,因此您选择的复选框将作为字符串存储到数组中,如果您选择另一个复选框,则字符串将被覆盖。第二个问题是,您将该存储的字符串称为数组。这导致您的字符串(一个字母数组)将为每个字母呈现。所以“数字”就像["N", "u", "m", "b", "e", "r"]
。
要解决您的问题,您需要将每个选择及其自己的引用存储在您的v-model
中。为了满足您正确列出和正确删除的需求,您需要应用以下更改:
你的复选框循环
<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
/>
你的 v-model
filter:
filterCollection: // Object instead of array
FilterPopUp.vue 中的方法
methods:
removeSelectedFilter(index)
delete this.filter.filterCollection[index];
,
isChecked(index)
return !!this.filter.filterCollection[index];
你的 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>
现在应该可以正确显示您的项目,正确删除项目并在删除项目后取消选中复选框。
【讨论】:
那么删除项目呢? :-) 非常感谢您的帮助,但现在我遇到了另一个问题,如果我单击所选列上的删除项目 SVG,它会删除该项目,但该框仍然在可用列中保持选中状态。有什么想法吗? @Fersek 由于 Tolbxela 的回答也导致该复选框仍处于选中状态,因此我编辑了我的回答,这应该可以满足您的需要。 @Fersek 在我的回答中对Checkbox.vue
和checkbox loop
进行了更改。它现在应该可以删除和取消选中。告诉我。
@StevenSiebert 现在就像一个魅力。非常感谢!【参考方案2】:
StevenSiebert 已正确指出您的错误。
但他的解决方案并不完整,因为当您取消选中其中一个过滤器时,不会从集合中删除过滤器。
这是我对您的复选框按预期工作的完整解决方案:
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);
,
,
...
这是工作的 CodeSandbox:
https://codesandbox.io/s/pensive-shadow-ygvzb?file=/src/components/Checkbox.vue
当然,有很多方法可以做到这一点。如果有人有更好更短的方法,请发布您的解决方案。看看会很有趣。
【讨论】:
这会导致在您从列表中删除项目后复选框仍然处于选中状态。 是的,你是对的。我不想自己做所有的工作。 :-)以上是关于具有 v-model 和项目数组的 Vue 3 自定义复选框组件的主要内容,如果未能解决你的问题,请参考以下文章
Vue.js 如何在 v-model 输入的数组中定位具有未知名称的对象