In a large Vue app using Vuetify, I have the following re-usable component used throughout the app:
<template>
<v-combobox
v-model="input"
:items="available"
:item-value="itemValue"
:item-text="itemText"
:label="label"
:disabled="disabled"
:hint="hint"
chips
multiple
persistent-hint
@input="myInput"
>
<template slot="selection" slot-scope="data">
<v-chip
:close="!disabled"
@input="remove(data.item)"
>
<strong>{{ data.item.code }}</strong>
</v-chip>
</template>
</v-combobox>
</template>
<script>
export default {
name: 'BaseSelectChip',
props: {
hint: String,
value: Array,
label: String,
available: Array,
disabled: Boolean,
itemText: {
type: String,
required: true,
},
itemValue: {
type: String,
required: true,
},
},
computed: {
input: {
get() {
return this.value;
},
set(val) {
this.$emit('input', val);
},
},
},
methods: {
myInput(items) {
this.input = [...this.items];
this.$emit('input', items);
},
remove(item) {
const newItems = this.input.slice();
newItems.splice(this.input.indexOf(item), 1);
this.$emit('input', newItems);
},
},
};
</script>
and it is typically used like so:
<BaseSelectChip
label="Liveness Options"
:value="tenantBiometricLiveness"
:available="getAvailableLiveness"
:disabled="!hasBiometric"
itemValue="code"
itemText="name"
:hint="livenessHint"
@input="livenessUpdated"
/>
To this point, all of the implementations in my app have allowed multiple selections, but I have a case where I want to limit it to a single selection. Per the docs, it is a a boolean, but also says that this prop Accepts array for value
. In addition, it states that the default value is false
, but when it is passed by itself to v-combobox
, it allows for multiple options to be selected. If I define a prop in BaseSelectChip
like so:
props: {
multiple: {
type: Boolean,
default: true,
},
}
and then pass it to v-combobox
<v-combobox
v-model="input"
:items="available"
:item-value="itemValue"
:item-text="itemText"
:label="label"
:disabled="disabled"
:hint="hint"
chips
:multiple="multiple"
persistent-hint
@input="myInput"
>
no matter how I pass it from the parent component, my screen is just blank, and I get no console warnings, which tells me Veutify is dying silently somewhere.
When I remove multiple
from the v-combobox
element, I get a blank item in my field, even though there is no item in the field (the items
prop):
In addition, if there is valid value passed to the field, removing the multiple
prop caused the data value to not be shown for some reason (the same result as when there is no data, as shown above).
So my questions are these:
1) How do I pass the value for the multiple
prop to <BaseSelectChip>
(and subsequently to v-combobox
) as needed by v-combobox
?
2) How can I configure the combobox to only allow one item to be selected at time, and only show a chip when an item is actually selected?
UPDATE: So to implement @skirtle's suggestion below: I modified BaseSelectChip
like so:
<v-combobox
v-model="input"
:items="available"
:item-value="itemValue"
:item-text="itemText"
:label="label"
:disabled="disabled"
chips
:multiple="multiple"
@input="myInput"
>
...
props: {
multiple: {
type: Boolean,
required: false,
default: true,
},
},
and then added :multiple="false"
in the parent component. That seems to work fine, but there's now one side effect: in BaseSelectChip
, the value that is emitted from myInput
(coming from the @input
event on the combobox) is an Observer
instead of an Array
. This causes problems in the parent component, because it's looking for an array. Why is it using an Observer?
multiple
but you're passing it tov-combobox
asmultipleItems
. – skirtle:multiple="false"
in the template that createsBaseSelectChip
. That should get you equivalent behaviour to omitting themultiple
attribute onv-combobox
. But that's just the start, you've got several lines of code that assume thevalue
will be an array. The docs line 'Accepts array for value' is a little confusing but it means that whenmultiple
istrue
thevalue
(bound withv-model
) will be an array. Ifmultiple
isfalse
then thevalue
will no longer be an array. – skirtle