Vueform Multiselect

repository·main·Indexed 21 days ago

https://github.com/vueform/multiselect

A highly customizable selection component for Vue.js supporting single select, multi-select, and tagging options. Features include async search, infinite scroll, object value support, grouped options, and compatibility with both Vue 3 and Vue 2 (with version constraints for Vue < 2.7).

Tokens
10K
Snippets
31
Records
45
Agent score
72%

What's inside @vueform/multiselect

  1. Use Custom Slots for Options and Labels

    main

    Multiselect provides several slots to customize the rendering of different parts of the component:

    • singlelabel: Customize the rendering of the selected value in single select mode.
    • multiplelabel: Customize the rendering of the selected values summary in multiple select mode.
    • option: Customize the rendering of each option in the dropdown list.
    • tag: Customize the rendering of selected tags in tags mode.
    <!-- Example: Customizing the option slot -->
    <Multiselect
      v-model="value"
      label="name"
      :options="options"
    >
      <template v-slot:option="{ option }">
        <img :src="option.icon"> {{ option.name }}
      </template>
    </Multiselect>
  2. Handle Async Default Values with `allowAbsent: true`

    main

    If your asynchronous :options returns an array of strings (where the string is both the label and the value), you can use :allow-absent="true" to allow v-model values that are not currently present in the loaded options list.

    <Multiselect
      mode="tags"
      v-model="value"
      :allow-absent="true"
      :resolve-on-load="false"
      :options="async (query) => await fetchLanguages(query)"
    />
    
    <script>
    export default {
      data: () => ({
        value: ['Java', 'JavaScript'] // These strings are not in the current options list
      })
    }
    </script>
  3. Handle Async Default Values with `object: true`

    main

    When using asynchronous options with resolveOnLoad: false, the component doesn't know the labels for values until the options are fetched. To provide default values in this scenario, set :object="true" and provide the v-model values as objects containing both label and value properties.

    <template>
      <Multiselect
        mode="tags"
        v-model="value"
        :object="true"
        :resolve-on-load="false"
        :options="async (query) => await fetchLanguages(query)"
      />
    </template>
    
    <script>
    export default {
      data: () => ({
        value: [
          { value: 'Java', label: 'Java' },
          { value: 'JavaScript', label: 'JavaScript' },
        ]
      })
    }
    </script>
  4. Customize Multiselect with Tailwind CSS

    main

    To use Multiselect with Tailwind CSS, follow these two steps:

    1. Configure Tailwind: Install mini-svg-data-uri and add the required background images to your tailwind.config.js to handle the caret, spinner, and remove icons.
    2. Import Theme: Import @vueform/multiselect/themes/tailwind.css in your main component's style block.

    Alternatively, you can skip the CSS import and pass Tailwind classes directly to the component using the :classes prop. Note that when using :classes, certain state-based classes (like dropdownTop or containerActive) are automatically merged with their base classes (like dropdown or container) by the component.

    // tailwind.config.js
    const svgToDataUri = require('mini-svg-data-uri')
    
    module.exports = {
      theme: {
        extend: {
          backgroundImage: (theme) => ({
            'multiselect-caret': `url("${svgToDataUri('<svg ...></svg>')}")`,
            'multiselect-spinner': `url("${svgToDataUri('<svg ...></svg>')}")`,
            'multiselect-remove': `url("${svgToDataUri('<svg ...></svg>')}")`,
          })
        }
      }
    }
    <style>
      @import '@vueform/multiselect/themes/tailwind.css';
    </style>
  5. Load Async Options with Infinite Scroll

    main

    To load large datasets efficiently, use :infinite="true" and :resolve-on-load="false". This prevents the component from loading options on mount and instead loads them when the user opens the dropdown. Use the @open event to trigger the initial resolution if no options are currently loaded.

    <Multiselect
      v-model="value"
      mode="tags"
      :resolve-on-load="false"
      :infinite="true"
      :limit="10"
      :options="async (query) => await fetchLanguages(query)"
      @open="(select$) => {
        if (select$.noOptions) {
          select$.resolveOptions()
        }
      }
    />
  6. Use Multiselect with Vue 3

    main

    To use the component in a Vue 3 application, import Multiselect from @vueform/multiselect and ensure you import the default theme CSS. Use v-model for data binding and :options to provide the selection list.

    <template>
      <div>
        <Multiselect
          v-model="value"
          :options="options"
        />
      </div>
    </template>
    
    <script>
      import Multiselect from '@vueform/multiselect'
    
      export default {
        components: {
          Multiselect,
        },
        data() {
          return {
            value: null,
            options: [
              'Batman',
              'Robin',
              'Joker',
            ]
          }
        }
      }
    </script>
    
    <style src="@vueform/multiselect/themes/default.css"></style>
  7. Use Multiselect with Vue 2

    main

    For Vue 2 projects, import the component from the specific Vue 2 distribution path: @vueform/multiselect/dist/multiselect.vue2.js. You must also import the default theme CSS.

    <template>
      <div>
        <Multiselect
          v-model="value"
          :options="options"
        />
      </div>
    </template>
    
    <script>
      import Multiselect from '@vueform/multiselect/dist/multiselect.vue2.js'
    
      export default {
        components: {
          Multiselect,
        },
        data() {
          return {
            value: null,
            options: [
              'Batman',
              'Robin',
              'Joker',
            ]
          }
        }
      }
    </script>
    
    <style src="@vueform/multiselect/themes/default.css"></style>
  8. Customize Multiselect with CSS Variables

    main

    When using default.css, you can customize the appearance of the Multiselect component by overriding CSS variables. You can apply these overrides globally using the :root selector or on a per-instance basis by applying a custom class to the component and defining the variables within that class.

    /* Global override */
    :root {
      --ms-tag-bg: #059669;
      --ms-tag-color: #D1FAE5;
      --ms-tag-radius: 9999px;
      --ms-tag-font-weight: 400;
    }
    
    /* Instance-level override */
    /* 
    <Multiselect class="multiselect-green" ... /> 
    */
    .multiselect-green {
      --ms-tag-bg: #D1FAE5;
      --ms-tag-color: #059669;
    }
    
    /* Available variables include: */
    /* --ms-font-size, --ms-bg, --ms-border-color, --ms-radius, --ms-tag-bg, --ms-tag-color, --ms-dropdown-bg, --ms-option-bg-selected, etc. */
  9. Configure search and filtering

    main

    When searchable: true is set, you can customize how users find options:

    • trackBy: The property or properties to search against (defaults to label).
    • searchFilter: A custom function (option, query, select$) => boolean to override the default search algorithm.
    • regex: A regular expression to test the search input against.
    • searchStart: If true, matches must occur at the start of the trackBy values.
    • strict: If true, respects accents/diacritics in search (default: true).
    • minChars: Minimum characters required before triggering an async refresh (default: 0).
    • delay: Milliseconds to wait after typing before refreshing async options (default: -1).
  10. Configure value and label mapping

    main

    When using an array of objects for options, use these props to map the object properties to the component's internal logic:

    • valueProp: The property used as the option's value (default: 'value').
    • label: The property used for the display text (default: 'label').
    • trackBy: The property used for searching (defaults to label).
    • disabledProp: The property used to determine if an option is disabled (default: 'disabled').
    • object: If true, the v-model will store the entire option object. If false, it stores only the value (default: false).