I have the following simple setup, and a client-side JavaScript application using Vue 3:
HTML (with select box):
<html> <head> <title>Test</title> </head> <body> <div id="vuetest"> <select id="assignment-select" v-model="ft_assignment"> <optgroup v-for="optgroup in ft_assignments" :label="optgroup.text"> <option v-for="option in optgroup.children" :value="option.id" :disabled="option.disabled" > {{ option.text }} </option> </optgroup> </select> </div> <script type="module"> import { createApp } from "https://unpkg.com/vue@3/dist/vue.esm-browser.js"; const app = createApp({ data() { return { ft_assignment: "a", ft_assignments: [ { text: "hi", children: [ { id: "a", text: "a1" }, { id: "b", text: "b1" }, ], }, { text: "there", children: [ { id: "c", text: "c1" }, { id: "d", text: "d1" }, ], }, ], }; }, watch: { ft_assignment(v) { console.log(v); }, }, }).mount("#vuetest"); </script> </body> </html>
I want to use a "nice" select box (e.g. vue-select or select2) with modern functionality like search - but I don't know how to include related components. I see a lot of warnings about mixing jQuery and Vue.js, so I avoid just using select2 as a jquery plugin and rendering it that way.
How to turn the selection box into a "better" more modern selection element?
P粉9869374572024-03-31 09:43:16
If you don't want to use a plugin and prefer to build it yourself (which I like to do).
To do this, you can create a div containing input type text that you can use to search for options within the div. These options are stored in a hidden div as anchor tags. Then, attach an event listener to the anchor tag element and the function it needs to call.
Take a look at this, you can of course edit it and make it work the way you need.
P粉1584737802024-03-31 00:32:02
This is not an esm build using vue 3, but still using UMD builds which are directly supported in the browser (the reason is that the vue-select library does not provide an esm build version, but it still supports UMD builds).
Basically include dependencies this way:
<script src="https://unpkg.com/vue@latest"></script> <script src="https://unpkg.com/vue-select@beta"></script> <link rel="stylesheet" href="https://unpkg.com/vue-select@latest/dist/vue-select.css" />
Then import vue
like this:
const { createApp } = Vue;
Then import the vue-select
component this way:
const app = createApp({ components: { vSelect: window["vue-select"], }, ...
Working code snippet:
<html>
<head>
<title>Test</title>
<script src="https://unpkg.com/vue@latest"></script>
<script src="https://unpkg.com/vue-select@beta"></script>
<link
rel="stylesheet"
href="https://unpkg.com/vue-select@latest/dist/vue-select.css"
/>
</head>
<body>
<div id="vuetest">
<v-select :options="flattenedFtAssignemnts" label="text"></v-select>
</div>
<script type="module">
const { createApp } = Vue;
const app = createApp({
components: {
vSelect: window["vue-select"],
},
data() {
return {
ft_assignment: "a",
ft_assignments: [
{
text: "hi",
children: [
{ id: "a", text: "a1" },
{ id: "b", text: "b1" },
],
},
{
text: "there",
children: [
{ id: "c", text: "c1" },
{ id: "d", text: "d1" },
],
},
],
};
},
computed: {
flattenedFtAssignemnts() {
return this.ft_assignments.map(obj => obj.children).flat();
}
},
watch: {
ft_assignment(v) {
console.log(v);
},
},
});
app.mount("#vuetest");
</script>
</body>
</html>