目录

一、Liquor Tree

入门 :

Development

Component Options 组件选项

Structure 结构

二、vue-treeselect

Introduction 介绍

Getting Started 入门


Vue 树形选择器( Vue tree select )组件在搭建 Vue 的 app 中特别常用,Vue tree select 除了简单的树形结构外,还有非常多样的功能来配合不同场景的使用。比如搜索过滤,前端添加删除树枝,前端编辑修改子树名,拖拽排序,对用户操作事件记录等。本文记录了我自己使用多年最好用的 2款 Vue tree select 组件,每一款都经过我实际测试,推荐给大家。


一、Liquor Tree

酒树(Liquor Tree)

Liquor Tree是一款轻量级树形选择器,对移动端友好,可拖放,支持键盘快捷键,每个操作动作都有事件记录,与 Vue 高度整合。Liquor Tree 代码简洁,扩展性强,可根据你的应用场景按需定制。

A Vue treecomponentthat allows you to present hierarchically organized data in a nice and logical manner.

Vue 树组件,可让您以美观和逻辑的方式呈现层次结构的数据。

supportsmobile, and has a variety of response events. Flexible configuration options, and support for keyboard navigation.

支持移动,并具有各种响应事件。 灵活的配置选项,并支持键盘导航。

View demo 查看演示 Documentation

github 地址 :

GitHub – amsik/liquor-tree: Tree component based on Vue.js


Vue 官方地址 :

Liquor Tree

产品特点 :

  • 拖放 移动友好
  • 每个动作的事件
  • 灵活的配置
  • 每页任意数量的实例
  • 多选
  • 键盘导航
  • 过滤
  • 分类
  • 与 Vuex 集成

入门 :

安装 :

Npm:

$ npm install liquor-tree

Yarn:

$ yarn add liquor-tree

要在自己的计算机上运行该演示,请执行以下操作:

克隆此存储库

  • npm install (npm安装 )
  • npm run build (npm运行构建)
  • npm run storybook
  • 访问 http://localhost:9001/

这里有很多例子供您参考。 所有来源都位于liquor-tree/docs/storybook/stories


它必须安装到 VueJS 实例中。请查看官方文档,了解如何使用 VueJS 组件 components

(当然,如果需要的话)。
您不需要关心样式,它们会自动附加到文档中。
当与模块系统一起使用时,有三种方法可以注册组件(可能更多…我不知道)。
好了,下面这是我们的方式:

import Vue from 'vue'import LiquorTree from 'liquor-tree'// global registrationVue.use(LiquorTree) // 第一种// orVue.component(LiquorTree.name, LiquorTree) // 第二种// orimport LiquorTree from 'liquor-tree'// local registrationexport default {name: 'your-awesome-component',components: {[LiquorTree.name]: LiquorTree // 第三种},...}

要注册库,您可以在我上面提到的 3 种方法之间进行选择。

当直接在浏览器中使用时,您可以通过CND包含liquor-tree(这是库的最新版本):


Usage 用法

import Vue from 'vue'import LiquorTree from 'liquor-tree'Vue.use(LiquorTree)export default {...data() {return {items: [{text: 'Item 1'},{text: 'Item 2'},{text: 'Item 3', children: [{text: 'Item 3.1'},{text: 'Item 3.2'}]},{text: '园区其他机构',children: [{text: '园区其他机构1',children: [{ text: '园区其他机构1.1.1' },{ text: '园区其他机构1.1.2' },{ text: '园区其他机构1.1.3' },],},{text: '园区其他机构2',children: [{ text: '园区其他机构2.1.1' },{ text: '园区其他机构2.1.2' },{ text: '园区其他机构2.1.3' },],},],},],options: {checkbox: true}}}...}

Development

Check out thepackage.jsons script section. There are 2 scripts:

  • npm run dev– it will open browser and you canplaywith code
  • npm run build– it will craete a module file inproductionmode

Component Options 组件选项

Name名称Type 类型DefaultDescription 描述
multipleBooleantrue

Allows to select more than one node.

允许选择多个节点

checkboxBooleanfalse

checkboxmode. It shows checkboxes for every node

复选框模式。它显示每个节点的复选框

checkOnSelectBooleanfalse

Forcheckboxmode only. Node will havecheckedstate when user clicks either text or checkbox

仅用于复选框模式。当用户单击文本或复选框时,节点将处于选中状态

autoCheckChildrenBooleantrue

Forcheckboxmode only. Children will have the samecheckedstate as their parent.

仅用于复选框模式。子级将具有与其父级相同的选中状态。

parentSelectBooleanfalse

By clicking node which has children it expands node. i.e we have two ways to expand/collapse node: by clicking on arrow and on text

通过单击具有子节点的节点,可以展开节点。即,我们有两种方法来展开/折叠节点:单击箭头和文本

keyboardNavigationBooleantrue

Allows user to navigate tree using keyboard

允许用户使用键盘浏览树

propertyNamesObject

This options allows the default tree’s structure to be redefined.See example

此选项允许重新定义默认树的结构。见示例

deletionBoolean | Functionfalse

IfkeyboardNavigationis false this property is ignored. This property defines deletion behaviour.See example

如果 keyboardNavigation 为 false ,则忽略此属性。此属性定义删除行为。见示例

fetchDataObjectSeeguide
dndObjectSeeguide 请参阅指南
editingObjectSeeguide

Structure 结构

The component has only two props:dataandoptions.该组件只有两个支柱:数据和选项。

  • propertyoptions– This property defines tree behavior. 属性选项 – 此属性定义树行为
  • propertydata– Array-like object that defines tree nodes.属性数据 – 定义树节点的类似数组的对象

关于Liquor Tree 树形组件的介绍就到此为止了,因为此组件未满足业务需求:搜索过滤功能。

再加上官方文档全都是英文的,所以就懒得再继续研究下去了。

因此另辟蹊径,找到了个人认为更加友好、更加优秀的一款 Tree 树形组件。

期间查询到一款应该还不错 :LyTree 树形组件 ( 貌似无搜索过滤 )

链接:tree树形组件 – DCloud 插件市场


二、vue-treeselect

@riophae/vue-treeselect

GitHub 地址:GitHub – riophae/vue-treeselect: A multi-select component with nested options support for Vue.jsA multi-select component with nested options support for Vue.js – GitHub – riophae/vue-treeselect: A multi-select component with nested options support for Vue.jshttps://github.com/riophae/vue-treeselect

Vue-TreeSelect 官网:Vue-TreeselectA multi-select component with nested options support for Vue.jshttps://vue-treeselect.js.org/

A multi-select component with nested options support for Vue.js

一个支持 Vue.js 的嵌套选项的多选组件


Introduction 介绍

vue-treeselect is a multi-select component with nested options support for Vue.js.

treeselecte 是一个具有嵌套选项的多选择组件,支持 Vue.js。

  • Single & multiple select with nested options support ( 支持嵌套选项的单个和多个选项 )
  • Fuzzy matching ( 模糊匹配 )
  • Async searching ( 异步搜索 )
  • Delayed loading ( load data of deep level options only when needed )
  • ( 支持嵌套选项的单个和多个选择 )
  • Keyboard support ( navigate using Arrow Up & Arrow Down keys, select option using Enter key, etc. ) ( 支持嵌套选项的单个和多个选择,使用回车键等 )
  • Rich options & highly customizable ( 丰富的选项和高度可定制的 )
  • Supports a wide range of browsers ( 支持多种浏览器 )

Requires Vue 2.2+ ( 必须 Vue 2.2+ )

Getting Started 入门

It’s recommended to install vue-treeselect via npm, and build your app using a bundler like webpack.

建议通过 npm 安装 vue-treeselect ,并使用类似 bundler 的 webpack 构建您的应用程序。

npm install --save @riophae/vue-treeselect

This example shows how to integrate vue-treeselect with your Vue SFCs.

这个示例展示了如何将 Vue 树选择与 Vue SFC 集成。

// import the componentimport Treeselect from '@riophae/vue-treeselect'// import the stylesimport '@riophae/vue-treeselect/dist/vue-treeselect.css'export default {// register the componentcomponents: { Treeselect },data() {return {// define the default valuevalue: null,// define optionsoptions: [ {id: 'a',label: 'a',children: [ {id: 'aa',label: 'aa',}, {id: 'ab',label: 'ab',} ],}, {id: 'b',label: 'b',}, {id: 'c',label: 'c',} ],}},}

If you just don’t want to use webpack or any other bundlers, you can simply include the standalone UMD build in your page. In this way, make sure Vue as a dependency is included before vue-treeselect.

如果你只是不想使用 webpack 或任何其他捆绑器,你可以简单地在你的页面中包括独立的UMD 构建。通过这种方式,确保在 Vue 树选择之前包含 Vue 作为依赖项。

// register the componentVue.component('treeselect', VueTreeselect.Treeselect)new Vue({el: '#app',data: {// define the default valuevalue: null,// define optionsoptions: [ {id: 'a',label: 'a',children: [ {id: 'aa',label: 'aa',}, {id: 'ab',label: 'ab',} ],}, {id: 'b',label: 'b',}, {id: 'c',label: 'c',} ],},})


个人实际项目所用 :

通过Treeselect组件的配置属性中添加"alwaysOpen": true来让搜索栏默认展开下拉

API – Props

props: {/** * 即使有禁用的选定节点,是否允许重置值 */allowClearingDisabled: {type: Boolean,default: false,}, /** * 选择/取消选择祖先节点时,是否应选择/取消选中其禁用的后代 * 和 allowClearingDisabled 一起使用 */allowSelectingDisabledDescendants: {type: Boolean,default: false,}, /** * 菜单是否应始终打开 */alwaysOpen: {type: Boolean,default: false,}, /** * 是否将菜单加到body上 */appendToBody: {type: Boolean,default: false,}, /** * 是否启用异步搜索模式 */async: {type: Boolean,default: false,}, /** * 是否自动将组件集中在装载上? */autoFocus: {type: Boolean,default: false,}, /** * 装载时自动加载根选项。当设置为“false”时,打开菜单时将加载根选项。 */autoLoadRootOptions: {type: Boolean,default: true,}, /** * 当用户取消选择一个节点时,会自动取消选择其祖先。仅适用于平面模式。 */autoDeselectAncestors: {type: Boolean,default: false,}, /** * 当用户取消选择节点时,会自动取消选择其子节点。仅适用于平面模式。 */autoDeselectDescendants: {type: Boolean,default: false,}, /** * 当用户选择一个节点时,会自动选择其祖先。仅适用于平面模式。 */autoSelectAncestors: {type: Boolean,default: false,}, /** * 当用户选择一个节点时,会自动选择其子节点。仅适用于平面模式。 */autoSelectDescendants: {type: Boolean,default: false,}, /** * 如果没有文本输入,按退格键是否删除最后一项。 */backspaceRemoves: {type: Boolean,default: true,}, /** * 在清除所有输入字段之前进行处理的函数。 * 返回“false”以防止清除值 * @type {function(): (boolean|Promise)} */beforeClearAll: {type: Function,default: constant(true),}, /** * 在叶节点之前显示分支节点? */branchNodesFirst: {type: Boolean,default: false,}, /** * 是否应该缓存每个搜索请求的结果? */cacheOptions: {type: Boolean,default: true,}, /** * 是否显示重置值的“×”按钮? */clearable: {type: Boolean,default: true,}, /** * 清楚文本,multiple为true时 */clearAllText: {type: String,default: 'Clear all',}, /** * 选择后是否清除搜索输入。 * 仅当“multiple”为“true”时使用。 * 对于单选模式,无论道具值如何,它总是**在选择一个选项后清除输入。 */clearOnSelect: {type: Boolean,default: false,}, /** * “×”按钮的标题。 */clearValueText: {type: String,default: 'Clear value',}, /** * 选择选项后是否关闭菜单? * 仅当“multiple”为“true”时使用。 */closeOnSelect: {type: Boolean,default: true,}, /** * 加载时应自动展开多少级别的分支节点。 * 设置Infinity以使所有分支节点在默认情况下展开。 */defaultExpandLevel: {type: Number,default: 0,}, /** * 在用户开始搜索之前要显示的默认选项集。用于异步搜索模式。 * 当设置为“true”时,将自动加载作为空字符串的搜索查询结果。 * @type {boolean|node[]} */defaultOptions: {default: false,}, /** * 如果没有文本输入,按delete键是否删除最后一项。 */deleteRemoves: {type: Boolean,default: true,}, /** * 用于连接隐藏字段值的多个值的分隔符。 */delimiter: {type: String,default: ',',}, /** * 仅显示与搜索值直接匹配的节点,不包括其祖先。 * * @type {Object} */flattenSearchResults: {type: Boolean,default: false,}, /** * 是否阻止选择分支节点? */disableBranchNodes: {type: Boolean,default: false,}, /** * 禁用控制? */disabled: {type: Boolean,default: false,}, /** * 是否禁用模糊匹配功能? */disableFuzzyMatching: {type: Boolean,default: false,}, /** *是否启用平面模式。非平面模式(默认)是指:* - 每当检查分支节点时,它的所有子节点也将被检查 * - 每当一个分支节点检查了所有子节点时,该分支节点本身也会被检查 * 设置“true”以禁用此机制 */flat: {type: Boolean,default: false,}, /** * 将以所有事件作为最后一个参数进行传递。 * 有助于识别事件的起源。*/instanceId: {// Add two trailing "$" to distinguish from explictly specified ids.default: () => `${instanceId++}$$`,type: [String, Number],}, /** * Joins multiple values into a single form field with the `delimiter` (legacy mode). * 使用“分隔符”将多个值合并到一个表单字段中(传统模式)。*/joinValues: {type: Boolean,default: false,}, /** * 限制所选选项的显示。 * 其余部分将隐藏在limitText字符串中。 */limit: {type: Number,default: Infinity,}, /** * Function that processes the message shown when selected elements pass the defined limit. * @type {function(number): string} */limitText: {type: Function,default: function limitTextDefault(count) { // eslint-disable-line func-name-matchingreturn `and ${count} more`},}, /** * Text displayed when loading options. */loadingText: {type: String,default: 'Loading...',}, /** * Used for dynamically loading options. * @type {function({action: string, callback: (function((Error|string)=): void), parentNode: node=, instanceId}): void} */loadOptions: {type: Function,}, /** * Which node properties to filter on. */matchKeys: {type: Array,default: constant(['label']),}, /** * Sets `maxHeight` style value of the menu. */maxHeight: {type: Number,default: 300,}, /** * Set `true` to allow selecting multiple options (a.k.a., multi-select mode). */multiple: {type: Boolean,default: false,}, /** * Generates a hidden  tag with this field name for html forms. */name: {type: String,}, /** * Text displayed when a branch node has no children. */noChildrenText: {type: String,default: 'No sub-options.',}, /** * Text displayed when there are no available options. */noOptionsText: {type: String,default: 'No options available.',}, /** * Text displayed when there are no matching search results. */noResultsText: {type: String,default: 'No results found...',}, /** * Used for normalizing source data. * @type {function(node, instanceId): node} */normalizer: {type: Function,default: identity,}, /** * By default (`auto`), the menu will open below the control. If there is not * enough space, vue-treeselect will automatically flip the menu. * You can use one of other four options to force the menu to be always opened * to specified direction. * Acceptable values: * - `"auto"` * - `"below"` * - `"bottom"` * - `"above"` * - `"top"` */openDirection: {type: String,default: 'auto',validator(value) {const acceptableValues = ['auto', 'top', 'bottom', 'above', 'below']return includes(acceptableValues, value)},}, /** * Whether to automatically open the menu when the control is clicked. */openOnClick: {type: Boolean,default: true,}, /** * Whether to automatically open the menu when the control is focused. */openOnFocus: {type: Boolean,default: false,}, /** * Array of available options. * @type {node[]} */options: {type: Array,}, /** * Field placeholder, displayed when there's no value. */placeholder: {type: String,default: 'Select...',}, /** * Applies HTML5 required attribute when needed. */required: {type: Boolean,default: false,}, /** * Text displayed asking user whether to retry loading children options. */retryText: {type: String,default: 'Retry" />

项目代码 :

添加机构取消// import the componentimport Treeselect from '@riophae/vue-treeselect';import '@riophae/vue-treeselect/dist/vue-treeselect.css';export default {// register the componentcomponents: { Treeselect },data() {return {// define the default selectedNodesselectedNodes: null,// define optionsoptions: [{id: '研发中心本部',label: '研发中心本部',children: [{id: '中心办公室',label: '中心办公室',children: [{ id: '张三', label: '张三' },{ id: '李四', label: '李四' },{ id: '王一一', label: '王一一' },],},{id: '中心技术二部',label: '中心技术二部',children: [{ id: '赵六', label: '赵六' },{ id: '七七', label: '七七' },{ id: '八八', label: '八八' },],},],},{id: '资源管理中心',label: '资源管理中心',children: [{id: '外部资源部1',label: '外部资源部1',children: [{id: '外部资源部1.1.1',label: '外部资源部1.1.1',},{id: '外部资源部1.1.2',label: '外部资源部1.1.2',},{id: '外部资源部1.1.3',label: '外部资源部1.1.3',},],},{id: '外部资源部2',label: '外部资源部2',children: [{id: '外部资源部2.1.1',label: '外部资源部2.1.1',},{id: '外部资源部2.1.2',label: '外部资源部2.1.2',},{id: '外部资源部2.1.3',label: '外部资源部2.1.3',},],},],},{id: '园区其他机构',label: '园区其他机构',children: [{id: '园区其他机构1',label: '园区其他机构1',children: [{id: '园区其他机构1.1.1',label: '园区其他机构1.1.1',},{id: '园区其他机构1.1.2',label: '园区其他机构1.1.2',},{id: '园区其他机构1.1.3',label: '园区其他机构1.1.3',},],},{id: '园区其他机构2',label: '园区其他机构2',children: [{id: '园区其他机构2.1.1',label: '园区其他机构2.1.1',},{id: '园区其他机构2.1.2',label: '园区其他机构2.1.2',},{id: '园区其他机构2.1.3',label: '园区其他机构2.1.3',},],},],},],};},methods: {// 自定义密钥名称normalize(options) {return {id: options.id,label: options.shortName,children: options.branchs,};},addInstitution() {if (!this.selectedNodes.length) {Notify('请先选择机构');return;}this.$emit('addInstitution', this.selectedNodes);},closeAddInstitution() {this.$emit('closeAddInstitution');},},};

未完待续 。。。


推荐文章:VueTreeselect_vue-treeselect_捡垃圾的小女孩的博客

https://www.cnblogs.com/webSnow/p/16043117.html