cvue-treeselect
v0.1.2
Published
A multi-select component with nested options support for Vue.js
Maintainers
Readme
TreeSelect 下拉树
树型选择器组件:支持单选、多选、懒加载(可支持搜索,自定义下拉框类名)、过滤数据、编辑信息时回显、判断当前节点是否需要禁用等功能
基础用法
:::demo
<template>
<div>
<ui-tree-select
:options="options"
placeholder="请选择你最喜欢的蔬菜或者水果"
v-model="value"
/>
</div>
</template>
<script>
export default {
data() {
return {
value: null,
options: [
{
id: "fruits",
label: "水果",
children: [
{
id: "apple",
label: "苹果 🍎",
},
{
id: "grapes",
label: "葡萄 🍇",
},
{
id: "pear",
label: "梨 🍐",
},
{
id: "strawberry",
label: "草莓 🍓",
},
{
id: "watermelon",
label: "西瓜 🍉",
},
],
},
{
id: "vegetables",
label: "蔬菜",
children: [
{
id: "corn",
label: "玉米 🌽",
},
{
id: "carrot",
label: "胡萝卜 🥕",
},
{
id: "eggplant",
label: "茄子 🍆",
},
{
id: "tomato",
label: "番茄 🍅",
},
],
},
],
};
},
};
</script>:::
多选模式
通过设置 multiple 属性为 true 来启用多选模式。在多选模式下,v-model 的值是一个数组,包含所有选中节点的值。
:::demo
<template>
<div>
<ui-tree-select
:options="options"
:multiple="true"
value-consists-of="ALL"
placeholder="请选择多个你喜欢的蔬菜或者水果"
v-model="value"
/>
</div>
</template>
<script>
export default {
data() {
return {
value: [],
options: [
{
id: "fruits",
label: "水果",
children: [
{
id: "apple",
label: "苹果 🍎",
},
{
id: "grapes",
label: "葡萄 🍇",
},
{
id: "pear",
label: "梨 🍐",
},
{
id: "strawberry",
label: "草莓 🍓",
},
{
id: "watermelon",
label: "西瓜 🍉",
},
],
},
{
id: "vegetables",
label: "蔬菜",
children: [
{
id: "corn",
label: "玉米 🌽",
},
{
id: "carrot",
label: "胡萝卜 🥕",
},
{
id: "eggplant",
label: "茄子 🍆",
},
{
id: "tomato",
label: "番茄 🍅",
},
],
},
],
};
},
};
</script>:::
更多特性
本示例展示了 TreeSelect 组件的多种配置选项,您可以通过勾选不同的选项来查看不同功能的效果。
:::demo
<template>
<div>
<div :dir="rtl ? 'rtl' : 'ltr'">
<ui-tree-select
name="demo"
:multiple="multiple"
:clearable="clearable"
:searchable="searchable"
:disabled="disabled"
:open-on-click="openOnClick"
:open-on-focus="openOnFocus"
:clear-on-select="clearOnSelect"
:close-on-select="closeOnSelect"
:always-open="alwaysOpen"
:append-to-body="appendToBody"
:options="options"
:limit="3"
:max-height="200"
v-model="value"
/>
</div>
<div class="value-display">当前值: {{ value }}</div>
<div class="control-panel">
<p>
<label><input type="checkbox" v-model="multiple" />多选</label>
<label><input type="checkbox" v-model="clearable" />可清空</label>
<label><input type="checkbox" v-model="searchable" />可搜索</label>
<label><input type="checkbox" v-model="disabled" />禁用</label>
</p>
<p>
<label><input type="checkbox" v-model="openOnClick" />点击时打开</label>
<label
><input type="checkbox" v-model="openOnFocus" />获取焦点时打开</label
>
</p>
<p>
<label
><input
type="checkbox"
v-model="clearOnSelect"
/>选择后清空搜索框</label
>
<label
><input
type="checkbox"
v-model="closeOnSelect"
/>选择后关闭菜单</label
>
</p>
<p>
<label><input type="checkbox" v-model="alwaysOpen" />始终打开</label>
<label
><input type="checkbox" v-model="appendToBody" />附加到body</label
>
<label><input type="checkbox" v-model="rtl" />RTL模式</label>
</p>
</div>
</div>
</template>
<script>
export default {
data() {
return {
multiple: true,
clearable: true,
searchable: true,
disabled: false,
openOnClick: true,
openOnFocus: false,
clearOnSelect: true,
closeOnSelect: false,
alwaysOpen: false,
appendToBody: false,
rtl: false,
value: ["a"],
options: [
{
id: "a",
label: "选项A",
children: [
{
id: "aa",
label: "选项A-1",
},
{
id: "ab",
label: "选项A-2",
},
],
},
{
id: "b",
label: "选项B",
children: [
{
id: "ba",
label: "选项B-1",
},
],
},
{
id: "c",
label: "选项C",
children: [
{
id: "ca",
label: "选项C-1",
},
],
},
],
};
},
watch: {
multiple(newValue) {
if (newValue) {
this.value = this.value ? [this.value] : [];
} else {
this.value = this.value[0];
}
},
},
};
</script>
<style>
.value-display {
margin-top: 10px;
padding: 8px 12px;
background-color: #f5f7fa;
border-radius: 4px;
color: #5e6d82;
}
.control-panel {
margin-top: 15px;
padding: 12px;
border: 1px solid #ebeef5;
border-radius: 4px;
}
.control-panel label {
margin-right: 15px;
display: inline-flex;
align-items: center;
}
.control-panel input[type="checkbox"] {
margin-right: 5px;
}
</style>:::
通过上面的交互示例,您可以体验 TreeSelect 组件的以下特性:
- 多选/单选模式切换
- 可清空选项
- 可搜索功能
- 禁用状态
- 点击/获取焦点时打开菜单
- 选择后是否清空搜索框
- 选择后是否关闭菜单
- 始终保持菜单打开
- 将菜单附加到 body 元素
- RTL(从右到左)文本方向支持
禁用特定节点
通过在节点对象中设置 isDisabled: true,可以禁用特定的选项。被禁用的选项不可被选中,但仍然可以展开(如果是分支节点)。
:::demo
<template>
<div>
<ui-tree-select
v-model="value"
:multiple="true"
:options="options"
placeholder="请选择项目..."
/>
</div>
</template>
<script>
export default {
data() {
return {
value: [],
options: [
{
id: "projects",
label: "项目",
children: [
{
id: "frontend",
label: "前端项目",
children: [
{
id: "vue",
label: "Vue项目",
},
{
id: "react",
label: "React项目",
isDisabled: true, // 禁用此选项
},
{
id: "angular",
label: "Angular项目",
},
],
},
{
id: "backend",
label: "后端项目",
isDisabled: true, // 禁用此选项及其所有子项
children: [
{
id: "java",
label: "Java项目",
},
{
id: "python",
label: "Python项目",
},
{
id: "nodejs",
label: "Node.js项目",
},
],
},
{
id: "mobile",
label: "移动端项目",
children: [
{
id: "ios",
label: "iOS项目",
isDisabled: true, // 禁用此选项
},
{
id: "android",
label: "Android项目",
},
{
id: "flutter",
label: "Flutter项目",
},
],
},
],
},
],
};
},
};
</script>:::
在上面的示例中:
- "React 项目"作为叶子节点被禁用
- "后端项目"作为分支节点被禁用,这意味着它的所有子节点也不可选择
- "iOS 项目"作为叶子节点被禁用
延迟加载
如果您有大量深层嵌套的选项,您可能希望在初始加载时只加载最顶层的选项,并在需要时才加载其余部分。您可以通过以下步骤实现:
- 通过设置
children: null声明一个未加载的分支节点 - 添加
loadOptions属性 - 每当展开未加载的分支节点时,将调用
loadOptions({ action, parentNode, callback, instanceId }),然后您可以执行从远程服务器请求数据的任务
:::demo
<template>
<div>
<ui-tree-select
:multiple="true"
:options="options"
:load-options="loadOptions"
noChildrenText="没有子节点.."
placeholder="展开任意文件夹选项..."
v-model="value"
/>
</div>
</template>
<script>
export default {
data() {
return {
value: null,
options: [
{
id: "success",
label: "包含子节点",
// 声明一个未加载的分支节点
children: null,
},
{
id: "no-children",
label: "没有子节点",
children: null,
},
{
id: "failure",
label: "演示错误处理",
children: null,
},
],
};
},
methods: {
loadOptions({ action, parentNode, callback }) {
// 通常,在这里执行AJAX操作
// 服务器响应后,将子选项分配给父节点并调用回调函数
// 模拟异步操作,而不是请求真实的API服务器(仅用于演示)
const simulateAsyncOperation = (fn) => {
setTimeout(fn, 2000);
};
if (action === "LOAD_CHILDREN_OPTIONS") {
switch (parentNode.id) {
case "success": {
simulateAsyncOperation(() => {
parentNode.children = [
{
id: "child",
label: "子选项",
},
];
callback();
});
break;
}
case "no-children": {
simulateAsyncOperation(() => {
parentNode.children = [];
callback();
});
break;
}
case "failure": {
simulateAsyncOperation(() => {
callback(new Error("加载选项失败:网络错误。"));
});
break;
}
default: /* empty */
}
}
},
},
};
</script>:::
懒加载模式下的回填
有时候,我们需要在懒加载模式下预先选中某些值,即使那些节点所在的分支尚未加载。TreeSelect 组件可以通过设置初始 v-model 的值来实现回填功能。
:::demo
<template>
<div>
<ui-tree-select
:multiple="true"
:options="options"
:load-options="loadOptions"
:default-options="defaultOptions"
placeholder="展示懒加载+回填功能"
v-model="value"
>
</ui-tree-select>
<div class="value-display">当前选中值: {{ value }}</div>
<div class="action-buttons">
<button class="demo-button" @click="resetSelection">重置选择</button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
value: ["1", "2"],
defaultOptions: [
{ id: "1", label: "南京市" },
{ id: "2", label: "苏州市" },
],
options: [
{
id: "region-1",
label: "华东地区",
children: null,
},
{
id: "region-2",
label: "华南地区",
children: null,
},
{
id: "region-3",
label: "华北地区",
children: null,
},
],
};
},
methods: {
loadOptions({ action, parentNode, callback }) {
// 模拟异步加载
const simulateAsyncOperation = (fn) => {
setTimeout(fn, 1000);
};
if (action === "LOAD_CHILDREN_OPTIONS") {
simulateAsyncOperation(() => {
console.log("Loading children for:", parentNode.id);
// 根据节点ID生成不同的子节点
if (parentNode.id === "region-1") {
parentNode.children = [
{ id: "1", label: "南京市" },
{ id: "2", label: "苏州市" },
{ id: "3", label: "杭州市" },
{ id: "4", label: "上海市" },
];
callback();
} else if (parentNode.id === "region-2") {
parentNode.children = [
{ id: "5", label: "广州市" },
{ id: "6", label: "深圳市" },
{ id: "7", label: "东莞市" },
];
callback();
} else if (parentNode.id === "region-3") {
parentNode.children = [
{ id: "8", label: "北京市" },
{ id: "9", label: "天津市" },
];
callback();
} else {
callback();
}
});
}
},
resetSelection() {
this.value = [];
},
},
};
</script>
<style>
.action-buttons {
margin-top: 15px;
display: flex;
gap: 10px;
}
.demo-button {
padding: 8px 15px;
background-color: #409eff;
border: none;
color: white;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s;
}
.demo-button:hover {
background-color: #66b1ff;
}
</style>:::
在上面的示例中,我们演示了如何在懒加载模式下实现回填功能:
树形结构设计:通过
children: null声明未加载的分支节点,构建了一个地区-城市的懒加载树。回填机制:我们使用
defaultOptions属性来解决回填时的标签显示问题:- 使用
defaultOptions属性:- 提供一个默认选项数组,包含 ID 和标签信息
- 在组件初始化时,虽然树节点还未加载,但通过 defaultOptions 可以正确显示已选项的标签
- 这种方式适用于不想修改
value格式(保持为 ID 数组)的场景
- 使用
懒加载处理:当用户展开相关分支时,TreeSelect 组件会根据
loadOptions函数加载必要的节点,并正确显示选中状态。
注意:除了使用
defaultOptions外,还可以使用value-format="object"并将v-model绑定的值设置为对象数组(每个对象包含id和label属性)来解决懒加载回填时的标签显示问题。这种方式直接提供了节点的标签信息,不依赖于节点的加载状态。
异步搜索
TreeSelect 支持根据用户输入动态加载和更改整个选项列表。默认情况下,TreeSelect 会缓存每个 AJAX 请求的结果,从而使用户的等待时间更少。
:::demo
<template>
<div>
<ui-tree-select
:multiple="true"
:async="true"
:load-options="loadOptions"
:defaultOptions="defaultOptions"
searchPromptText="请输入关键字搜索"
placeholder="请输入关键字搜索"
v-model="value"
/>
</div>
</template>
<script>
export default {
data() {
return {
value: ["1"],
defaultOptions: [{ id: "1", label: "方法1" }],
};
},
methods: {
loadOptions({ action, searchQuery, callback }) {
// 模拟异步操作
const simulateAsyncOperation = (fn) => {
setTimeout(fn, 2000);
};
if (action === "ASYNC_SEARCH") {
simulateAsyncOperation(() => {
// 根据搜索词生成选项
const options = [1, 2, 3, 4, 5].map((i) => ({
id: `${searchQuery}-${i}`,
label: `${searchQuery}-${i}`,
}));
callback(null, options);
});
}
},
},
};
</script>:::
多选模式下的值控制
在多选模式下,您可以通过 value-consists-of 属性控制 v-model 绑定值中应包含哪些节点。这对于确定选中状态的表现方式和数据提交格式至关重要。
:::demo
<template>
<div>
<ui-tree-select
:options="options"
:multiple="true"
:value-consists-of="valueConsistsOf"
placeholder="请选择多个选项..."
v-model="value"
/>
<div class="value-display">当前值: {{ value }}</div>
<p><strong>值包含模式:</strong></p>
<div class="value-mode-options">
<label
><input
type="radio"
value="BRANCH_PRIORITY"
v-model="valueConsistsOf"
/>BRANCH_PRIORITY - 分支节点优先</label
>
<label
><input
type="radio"
value="LEAF_PRIORITY"
v-model="valueConsistsOf"
/>LEAF_PRIORITY - 叶子节点优先</label
>
<label
><input type="radio" value="ALL" v-model="valueConsistsOf" />ALL -
包含所有选中节点</label
>
<label
><input
type="radio"
value="ALL_WITH_INDETERMINATE"
v-model="valueConsistsOf"
/>ALL_WITH_INDETERMINATE - 包含所有节点(含不确定状态)</label
>
</div>
<div class="usage-scenarios">
<p><strong>应用场景:</strong></p>
<ul>
<li>
<strong>BRANCH_PRIORITY</strong>:
适合权限配置、组织结构选择等场景,优先使用上级概念,数据更简洁
</li>
<li>
<strong>LEAF_PRIORITY</strong>:
适合商品选择、文件选择等场景,关注具体末端项目而非类别
</li>
<li>
<strong>ALL</strong>:
适合需要完整数据路径的表单提交,或需要显示完整选择路径的场景
</li>
<li>
<strong>ALL_WITH_INDETERMINATE</strong>:
适合需要保存精确选择状态并在后续恢复的复杂表单
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
data() {
return {
value: [],
valueConsistsOf: "BRANCH_PRIORITY",
options: [
{
id: "categories",
label: "商品类别",
children: [
{
id: "electronics",
label: "电子产品",
children: [
{
id: "phones",
label: "手机",
},
{
id: "laptops",
label: "笔记本电脑",
},
{
id: "tablets",
label: "平板电脑",
},
],
},
{
id: "clothing",
label: "服装",
children: [
{
id: "mens",
label: "男装",
},
{
id: "womens",
label: "女装",
},
],
},
],
},
],
};
},
};
</script>
<style>
.value-display {
margin-top: 10px;
padding: 8px 12px;
background-color: #f5f7fa;
border-radius: 4px;
color: #5e6d82;
word-break: break-all;
}
.value-mode-options {
display: flex;
flex-direction: column;
gap: 8px;
margin-bottom: 15px;
}
.value-mode-options label {
display: inline-flex;
align-items: center;
cursor: pointer;
}
.value-mode-options input {
margin-right: 5px;
}
.usage-scenarios {
margin-top: 15px;
padding: 12px;
border: 1px solid #ebeef5;
border-radius: 4px;
background-color: #fafbfc;
}
.usage-scenarios ul {
padding-left: 18px;
margin: 8px 0;
}
.usage-scenarios li {
margin-bottom: 8px;
line-height: 1.5;
}
</style>:::
value-consists-of 参数决定了多选模式下,当选中树节点时 v-model 绑定值中包含哪些节点 ID:
BRANCH_PRIORITY (默认) - 优先选择分支节点
- 当选中一个分支节点时,该节点会被添加到 value 中,但其子节点不会被包含
- 当一个分支节点的所有子节点都被选中时,只有父节点会出现在 value 中
- 这种模式简化了数据结构,使 value 数组更简洁
LEAF_PRIORITY - 优先选择叶子节点
- 当一个分支的所有叶子节点被选中时,value 中只包含这些叶子节点 ID,而不包含分支节点
- 适用于需要具体收集末端数据项的场景
ALL - 包含所有选中节点
- 当选中一个节点时,该节点及其所有选中的子节点 ID 都会被包含在 value 中
- 提供最完整的选择数据,适合需要知道完整选择路径的场景
ALL_WITH_INDETERMINATE - 包含所有节点及不确定状态节点
- 与 ALL 类似,但还包括处于"不确定"状态的节点(即部分子节点被选中的分支节点)
- 这是最全面的选择模式,提供了选择树的完整状态信息
扁平模式(父子不关联)与排序
在之前的所有示例中,我们使用了 TreeSelect 的默认非扁平模式,这意味着:
- 当选中一个分支节点时,其所有子节点也会被选中
- 当一个分支节点的所有子节点都被选中时,该分支节点本身也会被选中
有时我们不需要这种机制,希望分支节点和叶子节点不相互影响。在这种情况下,应该使用扁平模式,如下所示。
如果您想控制所选选项的显示顺序,请使用 sortValueBy 属性。该属性有三个选项:
"ORDER_SELECTED"(默认) - 按选择顺序"LEVEL"- 按选项级别:C 🡒 BB 🡒 AAA"INDEX"- 按选项索引:AAA 🡒 BB 🡒 C
:::demo
<template>
<div>
<ui-tree-select
:multiple="true"
:options="options"
:flat="true"
:sort-value-by="sortValueBy"
:default-expand-level="1"
placeholder="尝试选择一些选项"
v-model="value"
/>
<div class="value-display">当前值: {{ value }}</div>
<p><strong>排序方式:</strong></p>
<div class="sort-options">
<label
><input
type="radio"
value="ORDER_SELECTED"
v-model="sortValueBy"
/>按选择顺序</label
>
<label
><input type="radio" value="LEVEL" v-model="sortValueBy" />按级别</label
>
<label
><input type="radio" value="INDEX" v-model="sortValueBy" />按索引</label
>
</div>
</div>
</template>
<script>
export default {
data() {
return {
value: ["c", "aaa", "bb"],
options: [
{
id: "a",
label: "A",
children: [
{
id: "aa",
label: "AA",
children: [
{
id: "aaa",
label: "AAA",
},
{
id: "aab",
label: "AAB",
},
],
},
{
id: "ab",
label: "AB",
},
{
id: "ac",
label: "AC",
},
],
},
{
id: "b",
label: "B",
children: [
{
id: "ba",
label: "BA",
},
{
id: "bb",
label: "BB",
},
],
},
{
id: "c",
label: "C",
},
],
sortValueBy: "ORDER_SELECTED",
};
},
};
</script>
<style>
.value-display {
margin-top: 10px;
padding: 8px 12px;
background-color: #f5f7fa;
border-radius: 4px;
color: #5e6d82;
}
.sort-options {
display: flex;
gap: 20px;
}
.sort-options label {
display: inline-flex;
align-items: center;
cursor: pointer;
}
.sort-options input {
margin-right: 5px;
}
</style>:::
基本特性
此示例展示了 vue-treeselect 最常用的功能。通过输入几个字母可以尝试模糊匹配功能。
首先您需要学习如何定义选项。有两种类型的选项:a. 文件夹选项,可折叠且可能有子选项;b. 普通选项,不可折叠且没有子选项。这里,我们借用计算机科学的基本概念,将前者称为分支节点,后者称为叶子节点。这两种节点共同组成了树结构。
定义叶子节点非常简单:
{
id: '<id>', // 用于在树中标识选项,因此其值在所有选项中必须是唯一的
label: '<label>', // 用于显示选项
}定义分支节点只需一个额外的 children 属性:
{
id: '<id>',
label: '<label>',
children: [
{
id: '<child id>',
label: '<child label>',
},
...
],
}然后,您可以将这些节点的数组作为 options 属性传递。请注意,即使您为 children 属性分配了一个空数组,它仍被视为分支节点。这可能与您在计算机科学中学到的不同,在计算机科学中,没有子节点的节点通常被称为叶子节点。
有关节点对象中所有可用属性的信息,请参见下文。
TreeSelect 属性
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| --------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ------------------- | ---------------------------------------------------------------------- | --------------------------------------- |
| allowClearingDisabled | 是否允许在有禁用选中节点的情况下重置值 | Boolean | - | false |
| allowSelectingDisabledDescendants | 当选中/取消选中祖先节点时,是否应选中/取消选中其禁用的后代节点。您可能希望与 allowClearingDisabled 属性一起使用 | Boolean | - | false |
| alwaysOpen | 菜单是否应始终打开 | Boolean | - | false |
| appendToBody | 将菜单附加到 <body /> | Boolean | - | false |
| async | 是否启用异步搜索模式 | Boolean | - | false |
| autoFocus | 在组件加载时自动聚焦 | Boolean | - | false |
| autoLoadRootOptions | 在组件加载时自动加载根选项。设置为 false 时,仅在打开菜单时加载根选项 | Boolean | - | true |
| autoDeselectAncestors | 当用户取消选择节点时,自动取消选择其祖先节点。仅适用于平面模式 | Boolean | - | false |
| autoDeselectDescendants | 当用户取消选择节点时,自动取消选择其后代节点。仅适用于平面模式 | Boolean | - | false |
| autoSelectAncestors | 当用户选择节点时,自动选择其祖先节点。仅适用于平面模式 | Boolean | - | false |
| autoSelectDescendants | 当用户选择节点时,自动选择其后代节点。仅适用于平面模式 | Boolean | - | false |
| backspaceRemoves | 如果没有文本输入,按 Backspace 是否删除最后一项 | Boolean | - | true |
| beforeClearAll | 在清除所有输入字段之前处理的函数。返回 false 可阻止值被清除 | Function | - | () => true |
| branchNodesFirst | 在叶子节点之前显示分支节点 | Boolean | - | false |
| cacheOptions | 是否缓存异步搜索模式的每个搜索请求的结果 | Boolean | - | true |
| clearable | 是否显示一个"×"按钮来重置值 | Boolean | - | true |
| clearAllText | 多选模式下"×"按钮的标题 | String | - | "清除所有" |
| clearOnSelect | 选择选项后是否清除搜索输入。仅在多选模式下使用。对于单选模式,无论属性值如何,选择后始终清除输入 | Boolean | - | 多选模式下默认为 false,否则始终为 true |
| clearValueText | "×"按钮的标题 | String | - | "清除值" |
| closeOnSelect | 选择选项后是否关闭菜单。仅在多选模式下使用 | Boolean | - | true |
| defaultExpandLevel | 加载时应自动展开的分支节点的级别数。设置为 Infinity 可使所有分支节点默认展开 | Number | - | 0 |
| defaultOptions | 用户开始搜索前显示的默认选项集。用于异步搜索模式。设置为 true 时,将自动加载空字符串搜索查询的结果 | Boolean/Array | - | false |
| deleteRemoves | 如果没有文本输入,按 Delete 是否删除最后一项 | Boolean | - | true |
| delimiter | 用于连接多个值作为隐藏字段值的分隔符 | String | - | "," |
| flattenSearchResults | 搜索时是否扁平化树(仅限同步搜索模式) | Boolean | - | false |
| disableBranchNodes | 是否阻止选择分支节点 | Boolean | - | false |
| disabled | 是否禁用控件 | Boolean | - | false |
| disableFuzzyMatching | 设置为 true 可禁用默认启用的模糊匹配功能 | Boolean | - | false |
| flat | 是否启用平面模式 | Boolean | - | false |
| instanceId | 将与所有事件一起作为最后一个参数传递。用于识别事件来源 | String/Number | - | "<自动递增数字>$$" |
| joinValues | 使用 delimiter 将多个值连接到单个表单字段中(传统模式) | Boolean | - | false |
| limit | 限制显示选定选项的数量。其余将隐藏在 limitText 字符串中 | Number | - | Infinity |
| limitText | 处理超过定义限制时显示消息的函数 | Function | - | count => 和${count}个更多 |
| loadingText | 加载选项时显示的文本 | String | - | "加载中..." |
| loadOptions | 用于动态加载选项 | Function | - | - |
| matchKeys | 用于过滤 node 对象的键 | Array | - | [ "label" ] |
| maxHeight | 设置菜单的 maxHeight 样式值 | Number | - | 300 |
| multiple | 设置为 true 允许选择多个选项(又称多选模式) | Boolean | - | false |
| name | 为 HTML 表单生成带有此字段名的隐藏 <input /> 标签 | String | - | - |
| noChildrenText | 当分支节点没有子节点时显示的文本 | String | - | "没有子选项。" |
| noOptionsText | 没有可用选项时显示的文本 | String | - | "没有可用选项。" |
| noResultsText | 没有匹配的搜索结果时显示的文本 | String | - | "未找到结果..." |
| normalizer | 用于标准化源数据 | Function | - | node => node |
| openDirection | 菜单打开的方向,默认("auto")下,菜单将在控件下方打开。如果没有足够空间,vue-treeselect 将自动翻转菜单 | String | "auto", "below", "bottom", "above", "top" | "auto" |
| openOnClick | 是否在点击控件时自动打开菜单 | Boolean | - | true |
| openOnFocus | 是否在控件获得焦点时自动打开菜单 | Boolean | - | false |
| options | 可用选项数组 | Array | - | - |
| placeholder | 字段占位符,在没有值时显示 | String | - | "选择..." |
| required | 在需要时应用 HTML5 required 属性 | Boolean | - | false |
| retryText | 询问用户是否重试加载子选项时显示的文本 | String | - | "重试?" |
| retryTitle | 重试按钮的标题 | String | - | "点击重试" |
| searchable | 是否启用搜索功能 | Boolean | - | true |
| searchNested | 如果搜索查询也应在所有祖先节点中搜索,则设置为 true | Boolean | - | false |
| searchPromptText | 提示异步搜索的提示文本 | String | - | "输入搜索..." |
| showCount | 是否在每个分支节点的标签旁边显示子节点计数 | Boolean | - | false |
| showCountOf | 与 showCount 一起使用,指定应显示哪种类型的计数 | String | "ALL_CHILDREN", "ALL_DESCENDANTS", "LEAF_CHILDREN", "LEAF_DESCENDANTS" | "ALL_CHILDREN" |
| showCountOnSearch | 搜索时是否显示子节点计数。未指定时回退到 showCount 的值 | Boolean | - | - |
| sortValueBy | 选定选项在触发器中显示的顺序以及在 value 数组中排序的顺序。仅在多选模式下使用 | String | "ORDER_SELECTED", "LEVEL", "INDEX" | "ORDER_SELECTED" |
| tabIndex | 控件的 Tab 索引 | Number | - | 0 |
| value | 控件的值。当 :multiple="false" 时应为 id 或 node 对象;当 :multiple="true" 时应为 id 或 node 对象数组 | id/node/id[]/node[] | - | - |
| valueConsistsOf | 多选模式下 value 数组中应包含哪种类型的节点 | String | "ALL", "BRANCH_PRIORITY", "LEAF_PRIORITY", "ALL_WITH_INDETERMINATE" | "BRANCH_PRIORITY" |
| valueFormat | value 属性的格式。注意,当设置为 "object" 时,value 中每个 node 对象仅需要 id 和 label 属性 | String | "id", "object" | "id" |
| zIndex | 菜单的 z-index | Number/String | - | 999 |
TreeSelect 事件
| 事件名称 | 说明 | 回调参数 | | ------------- | ---------------------- | ------------------------------------------------- | | open | 菜单打开时触发 | (instanceId) 实例 ID | | close | 菜单关闭时触发 | (value, instanceId) 当前值,实例 ID | | input | 值变化后触发 | (value, instanceId) 当前值,实例 ID | | select | 选择某个选项后触发 | (node, instanceId) 所选节点,实例 ID | | deselect | 取消选择某个选项后触发 | (node, instanceId) 取消选择的节点,实例 ID | | search-change | 搜索查询变化后触发 | (searchQuery, instanceId) 搜索查询字符串,实例 ID |
节点对象属性
以下是节点对象可用的属性。
| 属性 | 类型 | 说明 | | ----------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | id (必填) | Number / String | 用于在树中标识选项,其值在所有选项中必须是唯一的 | | label (必填) | String | 用于显示选项 | | children | node[] / null | 声明一个分支节点。您可以:1) 设置为由 a.叶子节点,b.分支节点,或 c.这两者混合组成的子选项数组2) 设置为空数组表示没有子选项3) 设置为 null 以声明一个未加载的分支节点,用于延迟加载。您可以稍后在 loadOptions() 中重新分配一个数组(无论是否为空)来注册这些子选项,并将此分支节点标记为已加载如果要声明叶子节点,设置 children: undefined 或简单地省略此属性 | | isDisabled | Boolean | 用于禁用项目选择 | | isNew | Boolean | 用于给新节点不同的颜色 | | isDefaultExpanded | Boolean | 此文件夹选项是否应默认展开 |
label、children 或 isDisabled 的值可以随时重新分配。
除了上述列出的属性外,还可以添加更多属性。您甚至可以通过访问 node.raw.xxx 在自定义模板中使用这些额外的属性。
TreeSelect 插槽
| 插槽名 | 参数 | 说明 | | ------------ | ---------------------------------------------------------------- | ------------------------ | | option-label | { node, shouldShowCount, count, labelClassName, countClassName } | 自定义选项标签模板的插槽 | | value-label | { node } | 自定义值标签模板的插槽 | | before-list | - | 显示在菜单列表之前的插槽 | | after-list | - | 显示在菜单列表之后的插槽 |
