一、基本使用流程
首先npm安装依赖
npm install @riophae/vue-treeselect --save
然后在需要使用的组件中引入
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
声明组件
components: { Treeselect }
使用
<treeselect
:options="dataList" //接受数组
placeholder="请选择"
v-model="value"
/>
二、示例代码
1. 示例一
<template>
<div>
<treeselect v-model="deptIds" :options="deptList" :multiple="true" :disable-branch-nodes="false"
:clear-on-select="true" :flat="true" :show-count="true" placeholder="请选择" />
</div>
</template>
<script>
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
export default {
components: {
Treeselect
},
data() {
return {
deptList: [
{
id: 1,
label: 'a',
children: [
{
id: 4,
label: 'aa',
children: [
{
id: 6,
label: 'aaa',
}
],
}
],
},
{
id: 2,
label: 'b',
children: [
{
id: 5,
label: 'bb',
}
],
},
{
id: 3,
label: 'c',
children: [],
},
],
deptIds: [],
};
},
created() {
},
methods: {
},
};
</script>
<style scoped></style>
2. 示例二
<!-- Vue SFC -->
<template>
<div id="app" :dir="rtl ? 'rtl' : 'ltr'">
<!-- :auto-load-root-options="false" 装载时自动加载根选项。当设置为false时,将在打开菜单时加载根选项。 -->
<!-- :append-to-body="appendToBody" , 有时候下拉数据不显示,可以添加这个属性,
然后配合下面的样式 vue-treeselect__placeholder ; vue-treeselect__menu-container -->
<treeselect
v-model="value"
:options="options"
:normalizer="normalizer"
:multiple="multiple"
:append-to-body="appendToBody"
:flat="flat"
:show-count="showCount"
placeholder="请选择"
:load-options="loadOptions"
:flatten-search-results="false"
>
<!-- 自定义选项标签 -->
<!-- node -标准化的节点对象(请注意,这与您从normalizer() 返回的内容不同)
count & shouldShowCount - 计数数字和布尔值指示是否应显示计数
labelClassName & countClassName - CSS类名,用于使样式正确 -->
<label
slot="option-label"
slot-scope="{
node,
shouldShowCount,
count,
labelClassName,
countClassName,
}"
:class="labelClassName"
>
{{ node.isBranch ? "Branch" : "Leaf" }}: {{ node.label }}
<span v-if="shouldShowCount" :class="countClassName"
>({{ count }})</span
>
{{ showNode(node) }}
</label>
<!-- 自定义值标签 -->
<div slot="value-label" slot-scope="{ node }">
{{ node.raw.name }}(自定义)
</div>
</treeselect>
<el-button type="primary" @click="submit" style="margin-top: 20px"
>确认</el-button
>
</div>
</template>
<script>
// 引入组件和样式
// import the component
import Treeselect from "@riophae/vue-treeselect";
// import the styles
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
// -------------------延迟加载相关-------------------------
import { LOAD_CHILDREN_OPTIONS } from "@riophae/vue-treeselect";
//我们只是在这里使用“setTimeout()”来模拟异步操作
//而不是为了演示目的而请求真正的API服务器。
const simulateAsyncOperation = (fn) => {
setTimeout(fn, 2000);
};
export default {
// register the component 注册组件
components: { Treeselect },
name: "VueTreeselect",
data() {
return {
// define the default value 默认绑定值
value: null,
// define options 默认选项列表
options: [
{
key: "1",
name: "测试1",
subOptions: [
{
key: "1-1",
name: "测试1-1",
// 默认情况下是否应展开此文件夹选项。
isDefaultExpanded: true,
subOptions: [
{
key: "1-1-1",
name: "测试1-1-1",
// 用于为新节点赋予不同的颜色。
isNew: true,
},
{
key: "1-1-2",
name: "测试1-1-2",
},
],
},
{
key: "1-2",
name: "测试1-2",
},
],
},
{
key: "2",
name: "测试2",
subOptions: [
{
key: "2-1",
name: "测试2-1",
},
{
key: "2-2",
name: "测试2-2",
},
],
},
{
key: "3",
name: "测试3",
// Declare an unloaded branch node. 声明一个已卸载的分支节点
subOptions: null,
hasChildren: "success",
},
{
key: "4",
name: "测试4",
// isDisabled: true在任何叶节点或分支节点上进行设置来禁用项目选择
isDisabled: true,
},
{
key: "5",
name: "测试5",
// Declare an unloaded branch node.
subOptions: null,
hasChildren: "no-children",
},
{
key: "6",
name: "测试6",
// Declare an unloaded branch node.
subOptions: null,
hasChildren: "failure",
},
],
// --------------------------------------属性配置------------------------------------------------------
// 是否多选,默认false
multiple: true,
// 是否显示重置值的“×”按钮,默认true
clearable: true,
// 是否启用搜索功能。默认true
searchable: true,
// 是否禁用控制 (整体禁用)。默认false
disabled: false,
// 单击控件时是否自动打开菜单。默认true
openOnClick: true,
// 控件聚焦时是否自动打开菜单。 默认false
openOnFocus: true,
// 选择选项后是否清除搜索输入。仅在以下情况下使用:multiple=“true”。对于单选模式,无论道具值如何,它总是在选择后清除输入。
clearOnSelect: true,
// 选择一个选项后是否关闭菜单。仅在以下情况下使用:multiple=“true”。
closeOnSelect: true,
// 菜单是否应始终打开。
alwaysOpen: false,
// 将菜单附加到<body/>
appendToBody: true,
// 是否阻止选择分支节点
disableBranchNodes: false,
// 是否启用平面模式 (相当于父子节点分离)
flat: true,
// 是否在每个分支节点的标签旁边显示子计数
showCount: true,
// 控制文字显示,左对齐,还是右对齐
rtl: false,
// 限制所选选项的显示。其余部分将隐藏在limitText字符串中。
limit: 10,
// 默认展开几层
DefaultExpandLevel: 0,
// 巢状搜寻 该模式禁用了模糊匹配功能,以避免不匹配。
searchNested: false,
// 搜索时展平树 :flatten-search-results="true"
flattenSearchResults: true,
//防止价值组合
// "ALL" - 选中的所有节点都将包含在 value 数组中
// "BRANCH_PRIORITY"(默认)-如果选中了分支节点,则其所有后代将被排除在value 数组之外
// "LEAF_PRIORITY" - 如果选中了分支节点,则此节点本身及其分支后代将从value阵列中排除,但其叶后代将包括在内
// "ALL_WITH_INDETERMINATE" -选中的任何节点将包括在value 数组中,另外还有不确定的节点
valueConsistsOf: "BRANCH_PRIORITY",
// 平面模式和排序值 (选中的值的显示顺序) :sort-value-by="sortValueBy"
// "ORDER_SELECTED" (默认)-选择订单 (按照选中的顺序)
// "LEVEL" - 选择级别: C 🡒 BB 🡒 AAA (根据层级排序)
// "INDEX" - 选项索引: AAA 🡒 BB 🡒 C (根据索引排序)
sortValueBy: "ORDER_SELECTED",
// 是否启用异步搜索模式 :async="true"
async:false
};
},
methods: {
// 自定义键名:用于规范化源数据
normalizer(node) {
// console.log(node, "node");
return {
id: node.key,
label: node.name,
children: node.subOptions,
};
},
// 查看一下node里面有那些属性
showNode(node) {
console.log(node, "node");
},
// 延迟加载
// 通过设置声明一个卸载的分支节点children: null
// 添加 loadOptions
// 每当卸载的分支节点被扩展时, loadOptions({ action, parentNode, callback, instanceId }) 都会被调用,
// 然后您就可以执行从远程服务器请求数据的作业
loadOptions({ action, parentNode, callback }) {
console.log(action, "action");
console.log(parentNode, "parentNode");
console.log(callback, "callback");
if (action === LOAD_CHILDREN_OPTIONS) {
switch (parentNode.hasChildren) {
case "success": {
simulateAsyncOperation(() => {
parentNode.subOptions = [
{
key: "child",
name: "Child option",
},
];
callback();
});
break;
}
case "no-children": {
simulateAsyncOperation(() => {
parentNode.subOptions = [];
callback();
});
break;
}
case "failure": {
simulateAsyncOperation(() => {
callback(new Error("Failed to load options: network error."));
});
break;
}
default: /* empty */
}
}
},
// 查看选中的数据
submit() {
console.log(this.value, "查看选中的数据");
},
},
};
</script>
<style>
/* 修改字体大小 */
.vue-treeselect__placeholder {
color: #bdbdbd;
font-size: 14px;
}
/* 浮层内部样式 写在全局中 浮层被加入到了body里 */
.vue-treeselect__menu-container {
font-size: 14px;
color: #333;
font-weight: 400;
}
</style>
三、效果图