I had the same problem. I searched for some hours to find a solution to forward the value and event.
I started my research in reading source code and I find some interesting things. When you use v-model, vue.js generates a piece of code at runtime. These code retreat the event to simplify the assignement.
This save my life for the case when the select is not multiple, but the problem stayed. I suppose there is something similar for the binding of attribute value, but I didn't find it. If someone have it, I'm interested to have the source.
Finally I found a simple solution. The aim is just forwarding the v-model interactions of select (bind value and input event). I create a component with:
- computed property
model with a getter and setter.
- a
prop value.
With these, we take advantages of the generated piece of code with the setter, because the value passed is the refined value. The getter don't need to be more complex.
{
props: ["value"],
computed: {
model: {
get: () => {
// value is a prop of the component
return this.value;
},
set: (valueSelect) => {
this.$emit("input", valueSelect);
}
}
}
}
The template :
<template>
<select v-model="model">
<slot></slot>
</select>
</template>
I hope this help.
Sorry for the syntax, but I'm writing component in Typescript so it is really different. I write here in typescript and sfc syntax.
<script lang="ts">
import Vue from "vue";
import Component from "vue-class-component";
import { Prop, Watch } from "vue-property-decorator";
@Component
export default class SelectComponent extends Vue {
@Prop({
required: true
})
private value: any[] | any;
@Prop({
default: false
})
private multiple: boolean;
private get model() {
return this.value;
}
private set model(value) {
this.$emit("input", value);
}
}
</script>
<template>
<select v-model="model" :multiple="multiple">
<slot></slot>
</select>
</template>