Home  >  Q&A  >  body text

Use vue-select or another nice select box along with Vue 3's ESM vuild

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粉637866931P粉637866931188 days ago363

reply all(2)I'll reply

  • P粉986937457

    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.

    reply
    0
  • P粉158473780

    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>

    reply
    0
  • Cancelreply