vue-treeselectjs

Vue 3 tree select component with nested options, search, checkboxes, and multi-select support
21,517 110
Install
npm install vue-treeselectjs
Latest Version:1.0.2
Vue:3
License:MIT
Last Updated:Oct 22, 2026
Links: GitHub  ·  npm
Maintainer: zhuravkov888

Treeselect JS Vue component

vue-treeselectjs is a Vue 3 tree select component powered by the core https://www.npmjs.com/package/treeselectjs package.

Use it for nested options, searchable dropdowns, checkboxes, and multi-select inputs in Vue applications.

  • Full key support (ArrowUp, ArrowDown, Space, ArrowLeft, ArrowRight, Enter)
  • Screen-sensitive direction
  • Typescript support

Bundle sizes:

  • vue-treeselectjs.mjs 4.38 kB │ gzip: 1.54 kB
  • vue-treeselectjs.umd.js 4.15 kB │ gzip: 1.63 kB
  • vue-treeselectjs.css 8.49 kB │ gzip: 1.58 kB

Live Demo: https://dipson88.github.io/treeselectjs/

Example img

Support

You can buy me a coffee if you want to support my work. Thank you!

Getting Started

npm install --save vue-treeselectjs

Import vue-treeselectjs (ES)

import Treeselect from 'vue-treeselectjs'
import 'vue-treeselectjs/dist/vue-treeselectjs.css'

Import vue-treeselectjs (UMD)

<!DOCTYPE html>
<html>
  <head>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/treeselectjs/dist/treeselectjs.umd.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue-treeselectjs/dist/vue-treeselectjs.umd.js"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vue-treeselectjs/dist/vue-treeselectjs.css" />
  </head>
  <body>
      <div id="app">
        <vue-treeselect />
      </div>
      
      <script>
        const { createApp } = Vue
        const Treeselect = window.VueTreeselect;

        createApp({
          components: {
            VueTreeselect: Treeselect,
          }
        }).mount('#app')
      </script>
  </body>
</html>

All Available Imports

import Treeselect, { DirectionType, IconsType, OptionType, TreeselectValue, ... } from 'vue-treeselectjs'

Example

<template>
  <div class="App">
    <!-- Option 1 -->
    <Treeselect
      :model-value="modelValue"
      :options="options"
      @update:modelValue="onInput"
    >
      <div>Slot Content</div>
    </Treeselect>

    <!-- Option 2 -->
    <Treeselect
      v-model="modelValue"
      :options="options"
    >
      <div>Slot Content</div>
    </Treeselect>

    <!-- Option 3 -->
    <Treeselect
      :model-value="modelValue"
      :options="options"
      @input="onInput"
    >
      <div>Slot Content</div>
    </Treeselect>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue'
import Treeselect, { TreeselectValue } from 'vue-treeselectjs'
import 'vue-treeselectjs/dist/vue-treeselectjs.css'

export default defineComponent({
  name: 'App',
  components: {
    Treeselect
  },
  setup() {
    const options = ref([
      {
        name: 'England',
        value: 1,
        children: [
          {
            name: 'London',
            value: 2,
            children: [
              {
                name: 'Chelsea',
                value: 3,
                children: []
              },
              {
                name: 'West End',
                value: 4,
                children: []
              }
            ]
          },
          {
            name: 'Brighton',
            value: 5,
            children: []
          }
        ]
      },
      {
        name: 'France',
        value: 6,
        children: [
          {
            name: 'Paris',
            value: 7,
            children: []
          },
          {
            name: 'Lyon',
            value: 8,
            children: []
          }
        ]
      }
    ])

    const modelValue = ref<TreeselectValue>([3])

    // Also for value type, you can use: string | number | (string | number)[] | null
    const onInput = (value: TreeselectValue) => {
      console.log('onInput', value)
    }

    return {
      onInput,
      options,
      modelValue
    }
  }
})
</script>

Props

Core props
Name Type (default) Description
model-value Array[String | Number] | String | Number | null ([]) Selected value(s): array of ids (multi-select) or single id (single-select with isSingleSelect). Selected on load; updates when checkboxes/tags change.
options Array[Object] ([]) It is an array of objects {name: String, value: String | Number, disabled?: Boolean, htmlAttr?: object, isGroupSelectable?: boolean, children: [] }, where children are the same array of objects. Do not use duplicated value field. But you can use duplicated names. Read more.
disabled Boolean (false) List will be disabled.
id String ('') id attribute for the accessibility.
ariaLabel String ('') aria-label attribute for the accessibility.
isSingleSelect Boolean (false) Converts multi-select to the single value select. Checkboxes will be removed. You should pass only one id instead of array of values. Also you can set showTags to false. It helps to show treeselect as a dropdown.
isGroupedValue Boolean (false) Return groups if they selected instead of separate ids. Treeselect returns only leaves ids by default.
isIndependentNodes Boolean (false) All nodes in treeselect work as an independent entity. Check/uncheck action ignore children/parent updates workflow. Disabled nodes ignore children/parent workflow as well.
rtl Boolean (false) RTL mode.
isBoostedRendering Boolean (false) Experimental - Improves list rendering performance by using visibility-based optimizations and IntersectionObserver. Useful for efficiently rendering large lists.
List settings props
Name Type (default) Description
disabledBranchNode Boolean (false) It is impossible to select groups. You can select only leaves.
openLevel Number (0) All groups will be opened to this level.
appendToBody Boolean (false) List will be appended to the body instead of the input container.
alwaysOpen Boolean (false) List will be always opened. You can use it for comfortable style changing. If you want to use it as an opened list, turn staticList to true.
staticList Boolean (false) Add the list as a static DOM element. List doesn't overlap content. This prop will be ignored if you use appendToBody.
emptyText String ('No results found...') Empty list text.
direction String (auto) A force direction for the list. Supported values: auto, top, bottom.
expandSelected Boolean (false) All groups which have checked values will be expanded on the init.
saveScrollPosition Boolean (true) The list saves the last scroll position before close. If you open the list your scroll will be on the previous position. If you set the value to false - the scroll will have position 0 and the first item will be focused every time.
listClassName String ('') A class name for list. Useful to change styles for appendToBody mode.
Input settings props
Name Type (default) Description
showTags Boolean (true) Selected values look like tags. The false value shows results as '{count} elements selected'. You can change text if you use tagsCountText prop. For one selected element, you will see a name of this element.
tagsCountText String ('elements selected') Shown when showTags is false, after the count: '{count} {tagsCountText}'.
tagsSortFn (a: TagsSortItem, b: TagsSortItem) => number | null (null) Defines the sorting order for tags in the input field.TagsSortItem - { value: ValueOptionType, name: string }.
showCount Boolean (false) Shows count of children near the group's name.
clearable Boolean (true) Clear icon is available.
searchable Boolean (true) Search is available.
placeholder String ('Select...') Placeholder text.
grouped Boolean (true) Show groups in the input and group leafs if all group selected.
Emits
Name Type (default) Description
update:modelValue (value) => void (undefined) Emitted when the selection changes (used by v-model).
input (value) => void (undefined) Returns selected values when the list value changes.
open (value) => void (undefined) Returns selected values when the list is opened.
close (value) => void (undefined) Returns selected values when the list is closed.
name-change (name) => void (undefined) Returns the selected name in the input when it changes.
search (value) => void (undefined) Returns the search string when the user types. You can build autocomplete with this emit.
open-close-group ({ groupId, isClosed }: { groupId: TreeselectValue, isClosed: boolean }) => void (undefined) Returns groupId and open/closed status when a group is expanded or collapsed.
Additional props
Name Type (default) Description
iconElements Object({ arrowUp, ... }) Object containing all SVG icons. You can use HTMLElement or a String to reset values from the default Object. Object: iconElements: { arrowUp, arrowDown, arrowRight, attention, clear, cross, check, partialCheck }. After reset of icon you have to update styles if it is necessary, use alwaysOpen prop for more comfortable work with styles changes.

Slots
Name Type (default) Description
default undefined The slot's content will be mounted at the end of the list.

Option description

This is the shape of one option in the options prop:

Name Type Description
value String | Number (required!) It is a value of the node. It should be unique!
name String (required!) It is the name of the node. Can be duplicated.
disabled Boolean (optional) The node will be disabled. It is an optional field, you can skip it if no need to work with disabled values.
htmlAttr Object (optional) The object of the HTML attributes, the value of the object should be a String type. These attributes will be merged into the node HTML tag.
isGroupSelectable Boolean (optional - true) Determines whether groups are selectable. This behavior is similar to the disabledBranchNode prop but applies specifically to groups. It does not affect regular (non-group) items.
children { name: String, value: String | Number, disabled?: Boolean, htmlAttr?: object, children: [] }[] Children are the same array of objects.

Customizing colors

The component uses CSS custom properties (variables) for colors. Variables are defined on :root. Override them on :root (or body) so they apply to both the input and the dropdown list—especially when using appendToBody, since the list is then rendered outside the .treeselect container.

Variable Default Description
--treeselectjs-border-color #d7dde4 Border color of input and list
--treeselectjs-bg #ffffff Background of the input
--treeselectjs-border-focus #101010 Border color when focused
--treeselectjs-tag-bg #d7dde4 Background of selected tags
--treeselectjs-tag-bg-hover #c5c7cb Tag background on hover
--treeselectjs-tag-remove-hover #eb4c42 Remove (×) icon color on hover
--treeselectjs-icon #c5c7cb Arrow and clear icons
--treeselectjs-icon-hover #838790 Icons on hover
--treeselectjs-item-counter #838790 Group item count text
--treeselectjs-item-focus-bg #f0ffff List item background when focused
--treeselectjs-item-selected-bg #e9f1f1 List item background when selected
--treeselectjs-item-disabled-text #c5cbca Disabled item text color
--treeselectjs-checkbox-bg #ffffff Checkbox background
--treeselectjs-checkbox-border-color #d7dde4 Checkbox border color
--treeselectjs-checkbox-checked-bg #52c67e Checkbox fill when checked
--treeselectjs-checkbox-checked-icon #ffffff Checkmark color

Example:

body {
  --treeselectjs-border-color: #444;
  --treeselectjs-bg: #1e1e1e;
  --treeselectjs-border-focus: #6cb6ff;
  --treeselectjs-tag-bg: #333;
  --treeselectjs-tag-bg-hover: #444;
  --treeselectjs-item-focus-bg: #2a2a2a;
  --treeselectjs-item-selected-bg: #2d3a3a;
  --treeselectjs-checkbox-checked-bg: #52c67e;
  /* override other variables as needed */
}

Notes

  1. If you want to change the padding of the element you can use a CSS selector. I've added 'group' and 'level' attributes, but you have to use !important.
  2. Do not use duplicated values for the options. You will see an error with duplicated values. But you can use duplicated names.
  3. Value prop inside the options prop should be a String or Number.
  4. If you use isSingleSelect prop, you should pass only a single value without an array.
  5. If you use isSingleSelect prop, you can set showTags to false. It helps to show treeselect as a dropdown. You can also disable selecting group nodes with disabledBranchNode.
  6. If you use a large list of options and see a problem with performance, try to use isBoostedRendering prop.

License

MIT

Related Packages

treeselectjs

Vanilla JavaScript and TypeScript tree select component with nested options, sea...

110,815 110
@eav93/vue3-treeselect

Tree select component with nested options for Vue 3.5+ (TypeScript). A fork of v...

784 0
vue3-treeselect

Tree select hierarchical component for vue 3 (next)

296,815 100
@zanmato/vue3-treeselect

Tree select hierarchical component for Vue 3

179,982 25

Version History

Version Released License
1.0.2 MIT
1.0.1 MIT
1.0.0 MIT
0.9.2 MIT
0.9.1 MIT
Pre-releases (5)
Version Released License
1.0.0-beta.1 MIT
1.0.0-beta.0 MIT
0.9.2-beta.0 MIT
0.6.2-beta.1 MIT
0.6.2-beta.0 MIT