I have tried the sample in the doc and tried updating to use Vue 3 slot options and it still doesn't work. Has anyone gotten this to work.
Using the way the docs show it. https://vue-multiselect.js.org/#sub-custom-option-template
https://jsfiddle.net/c2e968g5
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vue-multiselect@3.0.0-beta.1/dist/vue-multiselect.esm.css" asp-append-version="true" />
<style>
/* Used to hide VueJS templates */
[v-cloak] {
display: none;
}
</style>
<script type="importmap">
{
"imports": {
"vue": "https://unpkg.com/vue@3.2.45/dist/vue.esm-browser.prod.js",
"vue_multiselect": "https://cdn.jsdelivr.net/npm/vue-multiselect@3.0.0-beta.1/dist/vue-multiselect.esm.min.js"
}
}
</script>
<script type="module">
import { createApp } from 'vue'
import VueMultiselect from "vue_multiselect";
const app = createApp({
data() {
return {
value: null,
options: [{ name: "John", last: "Smith" }, { name: "Bob", last: "Chair" }, {name:"Chuck",last:"Norris"}]
}
},
components: {
vuemultiselect: VueMultiselect
}
}).mount('#app');
</script>
<div id="app" v-cloak>
<vuemultiselect
v-model="value"
placeholder="Start typing to find address"
open-direction="bottom"
:options="options"
:options-limit="100"
:limit="20"
:searchable="true"
:hide-selected="false"
:close-on-select="true"
:clear-on-select="false"
:multiple="false"
:internal-search="true"
:max-height="300"
:show-no-results="false"
:preserve-search="false"
:allow-empty="true"
:reset-after="false">
<template slot="singleLabel" slot-scope="props">
<span>{{props.option.name}}</span>
</template>
<template slot="option" slot-scope="props">
<b>{{props.option.name}}</b>
<br />
<span>{{props.option.last}}</span>
</template>
</vuemultiselect>
</div>
Using new Vue 3 slot options
https://jsfiddle.net/c2e968g5/1/
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vue-multiselect@3.0.0-beta.1/dist/vue-multiselect.esm.css" asp-append-version="true" />
<style>
/* Used to hide VueJS templates */
[v-cloak] {
display: none;
}
</style>
<script type="importmap">
{
"imports": {
"vue": "https://unpkg.com/vue@3.2.45/dist/vue.esm-browser.prod.js",
"vue_multiselect": "https://cdn.jsdelivr.net/npm/vue-multiselect@3.0.0-beta.1/dist/vue-multiselect.esm.min.js"
}
}
</script>
<script type="module">
import { createApp } from 'vue'
import VueMultiselect from "vue_multiselect";
const app = createApp({
data() {
return {
value: null,
options: [{ name: "John", last: "Smith" }, { name: "Bob", last: "Chair" }, {name:"Chuck",last:"Norris"}]
}
},
components: {
vuemultiselect: VueMultiselect
}
}).mount('#app');
</script>
<div id="app" v-cloak>
<vuemultiselect
v-model="value"
placeholder="Start typing to find address"
open-direction="bottom"
:options="options"
:options-limit="100"
:limit="20"
:searchable="true"
:hide-selected="false"
:close-on-select="true"
:clear-on-select="false"
:multiple="false"
:internal-search="true"
:max-height="300"
:show-no-results="false"
:preserve-search="false"
:allow-empty="true"
:reset-after="false">
<template slot="singleLabel" v-slot="{ name }">
<span>{{name}}</span>
</template>
<template slot="option" v-slot="{ name, last }">
<b>{{name}}</b>
<br />
<span>{{last}}</span>
</template>
</vuemultiselect>
</div>
The right way to write it is:
<template v-slot:option="{ option }">
<b>{{ option.name }}</b>
</template>
or shorthand:
<template #option="{ option }">
<b>{{ option.name }}</b>
</template>
So there is no slot
property anymore, and the slot name goes after the v-slot:
(or the shorthand #
), slot props follow the statement immediately:
v-slot:option="{ option, search, index }"
The problem with the singleLabel
slot is particular to your setup, where you are using the multiselect in HTML directly, and not in a component, which means that the browser sees it before Vue does and performs changes to it.
So from a statement like
<template v-slot:singleLabel="{ option }">
the camelCased singleLabel
is turned into lowercase singlelabel
:
<template v-slot:singlelabel="{ option }">
But that slot indeed does not exist.
The problem does not occur if you put the vuemultiselect in a component, see the fiddle.
If that is not an option, as a hack, you could use a dynamic slot:
<template v-slot:[slotname]="{ option }">
where slotname
(again, lowercase) is a variable containing the slot name as a string, i.e. "singleLabel"
.