Notes
Autocomplete
Enable autocomplete mode with the autocomplete
prop. You can also use v-autocomplete
component which is just v-select
with autocomplete
automatically turned on. In autocomplete mode no-filter
, no-pagination
and is-loading
props can be used when requesting data from API.
Example - simple select
<template>
<div class="flex flex-col md:flex-row md:items-center">
<div class="w-full md:w-1/2">
<v-select
v-model="example.model"
:items="example.items"
></v-select>
</div>
<div class="md:ml-10 mt-6 md:mt-0">
<span class="font-semibold">v-model:</span>
{{ example.model }}
</div>
</div>
</template>
<script setup>
import { reactive } from "vue";
import { languages } from "../example-data/data.js";
let example = reactive({
model: "",
items: languages,
});
</script>
Example - simple select (multiple)
<template>
<div class="flex flex-col md:flex-row md:items-center">
<div class="w-full md:w-1/2">
<v-select
v-model="example.model"
:items="example.items"
multiple
></v-select>
</div>
<div class="w-1/2 md:ml-10 mt-6 md:mt-0">
<span class="font-semibold">v-model:</span>
{{ example.model }}
</div>
</div>
</template>
<script setup>
import { reactive } from "vue";
import { languages } from "../example-data/data.js";
let example = reactive({
model: [],
items: languages,
});
</script>
Example - autocomplete
This example uses no-filter
prop and simple mock of API request. It does not perform local autocompletion, instead items
prop is replaced or updated with new set of items after input event.
<template>
<div class="flex flex-col md:flex-row md:items-center">
<div class="w-full md:w-1/2">
<v-autocomplete
v-model="example.model"
no-filter
:items="example.items"
:state="example.state"
:is-loading="example.isLoading"
@input:value="query($event)"
v-on="handleExampleEvents"
></v-autocomplete>
</div>
<div class="md:ml-10 mt-6 md:mt-0">
<span class="font-semibold">v-model:</span>
{{ example.model }}
</div>
</div>
</template>
<script setup>
import { ref, reactive } from "vue";
import { states } from "../example-data/data.js";
let example = reactive({
model: "",
items: [],
});
let query = (q) => {
if (q === "") return example.items;
example.isLoading = true;
setTimeout(() => {
example.items = states.filter((e) => {
return (e.text || "").toLowerCase().indexOf((q || "").toLowerCase()) > -1;
});
example.isLoading = false;
}, 500);
};
let events = ref([]);
let handleExampleEvents = {
["update:page"]: (event) =>
events.value.unshift({ ev: "update:page", data: event }),
["state:focus"]: (event) =>
events.value.unshift({ ev: "state:focus", data: event }),
["state:opened"]: (event) =>
events.value.unshift({ ev: "state:opened", data: event }),
["state:closed"]: (event) =>
events.value.unshift({ ev: "state:closed", data: event }),
["input:value"]: (event) =>
events.value.unshift({ ev: "input:value", data: event }),
};
</script>
Example - autocomplete (multiple with chips)
Example of multi value autocomplete that uses v-chip
components to display selected values.
<template>
<div class="flex flex-col md:flex-row md:items-center">
<div class="w-full md:w-1/2">
<v-autocomplete
v-model="example.model"
no-filter
multiple
:items="example.items"
:is-loading="example.isLoading"
@input:value="query($event)"
>
<template #selected-item="{ item }">
<v-chip
class="my-1 mr-2"
@click:close-button="remove(item.value)"
>
{{ item.text }}
</v-chip>
</template>
</v-autocomplete>
</div>
<div class="w-full md:w-1/2 md:ml-10 mt-6 md:mt-0">
<span class="font-semibold">v-model:</span>
{{ example.model }}
</div>
</div>
</template>
<script setup>
import { reactive } from "vue";
import { states } from "../example-data/data.js";
let example = reactive({
model: [],
items: [],
isLoading: false,
});
let query = (q) => {
if (q === "") return example.items;
example.isLoading = true;
setTimeout(() => {
example.items = states.filter((e) => {
return (e.text || "").toLowerCase().indexOf((q || "").toLowerCase()) > -1;
});
example.isLoading = false;
}, 500);
};
let remove = (item) => {
const index = example.model.indexOf(item);
if (index >= 0) example.model.splice(index, 1);
};
</script>
Example - autocomplete (Wikipedia API)
<template>
<div class="flex items-center">
<div class="w-1/2">
<v-autocomplete
v-model="example.model"
no-filter
item-text="title"
item-value="pageid"
:items="example.items"
:state="example.state"
:is-loading="example.isLoading"
:offset-y="0"
:input="{ base: 'underlinedInput' }"
@input:value="debouncedQuery($event)"
></v-autocomplete>
</div>
<div class="ml-10">
<span class="font-semibold">v-model:</span>
{{ example.model }}
</div>
</div>
<v-card
v-if="current"
mod-card="shape:square border:borderless"
class="p-4 mt-6"
>
<ul>
<li>
<span class="font-semibold">
{{ current.title }}
</span>
</li>
<li class="my-4">
<a
:href="`https://en.wikipedia.org/?curid=${current.pageid}`"
class="link"
>
{{ `https://en.wikipedia.org/?curid=${current.pageid}` }}
</a>
</li>
</ul>
<iframe
v-if="current"
:src="`https://en.wikipedia.org/?curid=${current.pageid}`"
frameborder="0"
class="w-full h-[600px]"
></iframe>
</v-card>
</template>
<script setup>
import { reactive, computed } from "vue";
import { debounce } from "../../tools.js";
let example = reactive({
model: "",
items: [],
});
const urlWiki =
"https://en.wikipedia.org/w/api.php?action=query&format=json&list=prefixsearch&formatversion=2&origin=*&pssearch=";
let current = computed(() => {
return example.items.find((i) => i.pageid === example.model);
});
let query = async (q) => {
if (q === "") return example.items;
example.isLoading = true;
let res = await fetch(`${urlWiki}${q}`)
let data = await res.json()
example.items = data.query.prefixsearch
example.isLoading = false;
};
let debouncedQuery = debounce(query, 300);
</script>
Example - autocomplete (customized menu)
To customize menu items use item
slot.
<template>
<div class="flex items-center">
<div class="w-1/2">
<v-autocomplete
v-model="example.model"
:items="example.items"
:is-loading="example.isLoading"
item-text="full_name"
item-value="id"
no-filter
@input:value="query($event)"
>
<template #menu-item="{ item, isSelected, highlight }">
<div class="flex justify-between">
<div
v-html="
isSelected ? item['full_name'] : highlight(item['full_name'])
"
></div>
<div class="text-xs">{{ item.department }}</div>
</div>
<span class="text-sm font-semibold">
{{ item.title }}
</span>
</template>
</v-autocomplete>
</div>
<div class="ml-10 w-1/2">
<span class="font-semibold">v-model:</span>
{{ example.model }}
</div>
</div>
</template>
<script setup>
import { reactive } from "vue";
import company from "../example-data/company.json";
let example = reactive({
model: "",
items: [],
isLoading: false,
});
let query = (q) => {
if (q === "") return;
example.isLoading = true;
setTimeout(() => {
example.items = company.filter((e) => {
return (
(e["full_name"] || "").toLowerCase().indexOf((q || "").toLowerCase()) >
-1
);
});
example.isLoading = false;
}, 500);
};
</script>
Example - select (max multiple limit)
max-multiple
prop sets the max number of selected items shown in the input. In the following example max-multiple
slot is used to show the number of remaining hidden items.
<template>
<div class="flex flex-col md:flex-row md:items-center">
<div class="w-full md:w-1/2">
<v-select
v-model="example.model"
:items="example.items"
multiple
:max-multiple="2"
>
<template #max-multiple>
(+{{ example.model.length - 2}} others)
</template>
</v-select>
</div>
<div class="w-1/2 md:ml-10 mt-6 md:mt-0">
<span class="font-semibold">v-model:</span>
{{ example.model }}
</div>
</div>
</template>
<script setup>
import { reactive } from "vue";
import { languages } from "../example-data/data.js";
let example = reactive({
model: [],
items: languages,
});
</script>