Vue通用下拉树组件@riophae/vue-treeselect的使用

这篇具有很好参考价值的文章主要介绍了Vue通用下拉树组件@riophae/vue-treeselect的使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这个是在若依框架无意中发现的一个下拉树通用组件。@riophae/vue-treeselect 是一个基于 Vue.js 的树形选择器组件,可以用于选择树形结构的数据。它支持多选、搜索、异步加载等功能,可以自定义选项的样式和模板。该组件易于使用和扩展,适用于各种类型的项目。

npm:https://www.npmjs.com/package/@riophae/vue-treeselect 

首先安装: 

 使用自己习惯使用的包管理器安装就可以了

pnpm add @riophae/vue-treeselect

引入注册: 

import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'

export default {
  components: { Treeselect } 
}

基本使用:

<template>
  <div id="app">
    <treeselect v-model="value" :multiple="true" :options="options" />
  </div>
</template>

<script>
  // import the component
  import Treeselect from '@riophae/vue-treeselect'
  // import the styles
  import '@riophae/vue-treeselect/dist/vue-treeselect.css'

  export default {
    // register the component
    components: { Treeselect },
    data() {
      return {
        // define the default value
        value: null,
        // define options
        options: [ {
          id: 'a',
          label: 'a',
          children: [ {
            id: 'aa',
            label: 'aa',
          }, {
            id: 'ab',
            label: 'ab',
          } ],
        }, {
          id: 'b',
          label: 'b',
        }, {
          id: 'c',
          label: 'c',
        } ],
      }
    },
  }
</script>

里面可配置的属性很多,下面是在源码中看到的: 

部分注释百度翻译成中文了,但太多了,懒得挨个翻译了,直接看也大概知道啥意思 

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<boolean>)}
   */
  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-matching
      return `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 <input /> 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?',
  },

  /**
   * Title for the retry button.
   */
  retryTitle: {
    type: String,
    default: 'Click to retry',
  },

  /**
   * Enable searching feature?
   */
  searchable: {
    type: Boolean,
    default: true,
  },

  /**
   * Search in ancestor nodes too.
   */
  searchNested: {
    type: Boolean,
    default: false,
  },

  /**
   * Text tip to prompt for async search.
   */
  searchPromptText: {
    type: String,
    default: 'Type to search...',
  },

  /**
   * Whether to show a children count next to the label of each branch node.
   */
  showCount: {
    type: Boolean,
    default: false,
  },

  /**
   * Used in conjunction with `showCount` to specify which type of count number should be displayed.
   * Acceptable values:
   *   - "ALL_CHILDREN"
   *   - "ALL_DESCENDANTS"
   *   - "LEAF_CHILDREN"
   *   - "LEAF_DESCENDANTS"
   */
  showCountOf: {
    type: String,
    default: ALL_CHILDREN,
    validator(value) {
      const acceptableValues = [ALL_CHILDREN, ALL_DESCENDANTS, LEAF_CHILDREN, LEAF_DESCENDANTS]
      return includes(acceptableValues, value)
    },
  },

  /**
   * Whether to show children count when searching.
   * Fallbacks to the value of `showCount` when not specified.
   * @type {boolean}
   */
  showCountOnSearch: null,

  /**
   * In which order the selected options should be displayed in trigger & sorted in `value` array.
   * Used for multi-select mode only.
   * Acceptable values:
   *   - "ORDER_SELECTED"
   *   - "LEVEL"
   *   - "INDEX"
   */
  sortValueBy: {
    type: String,
    default: ORDER_SELECTED,
    validator(value) {
      const acceptableValues = [ORDER_SELECTED, LEVEL, INDEX]
      return includes(acceptableValues, value)
    },
  },

  /**
   * Tab index of the control.
   */
  tabIndex: {
    type: Number,
    default: 0,
  },

  /**
   * The value of the control.
   * Should be `id` or `node` object for single-select mode, or an array of `id` or `node` object for multi-select mode.
   * Its format depends on the `valueFormat` prop.
   * For most cases, just use `v-model` instead.
   * @type {?Array}
   */
  value: null,

  /**
   * Which kind of nodes should be included in the `value` array in multi-select mode.
   * Acceptable values:
   *   - "ALL" - Any node that is checked will be included in the `value` array
   *   - "BRANCH_PRIORITY" (default) - If a branch node is checked, all its descendants will be excluded in the `value` array
   *   - "LEAF_PRIORITY" - If a branch node is checked, this node itself and its branch descendants will be excluded from the `value` array but its leaf descendants will be included
   *   - "ALL_WITH_INDETERMINATE" - Any node that is checked will be included in the `value` array, plus indeterminate nodes
   */
  valueConsistsOf: {
    type: String,
    default: BRANCH_PRIORITY,
    validator(value) {
      const acceptableValues = [ALL, BRANCH_PRIORITY, LEAF_PRIORITY, ALL_WITH_INDETERMINATE]
      return includes(acceptableValues, value)
    },
  },

  /**
   * Format of `value` prop.
   * Note that, when set to `"object"`, only `id` & `label` properties are required in each `node` object in `value` prop.
   * Acceptable values:
   *   - "id"
   *   - "object"
   */
  valueFormat: {
    type: String,
    default: 'id',
  },

  /**
   * z-index of the menu.
   */
  zIndex: {
    type: [Number, String],
    default: 999,
  }
}

然后我简单看了一下好像一共向外暴露了6个方法如下:

@input // // 选中触发(第一次回显的时候会触发,清除值的时候会触发, value值为undefined) input事件用于v-model双向绑定组件更新父组件值

@select // 选中触发(清除值的时候不会触发)

@deselect // 移除选项时触发 当设置multiple为true时生效  raw为当前移除的对象

@search-change // 搜索触发(输入框输入 值改变时)

@open // 展开时触发

@close // 关闭时触发

下面是我测试的一个例子,一般的需求应该足够了

字体样式简单调了一下 

<template>
  <div class="main">
    <div class="tree">
      <Treeselect 
        v-model="value"
        :options="options"
        :placeholder="'请选择人员'"
        :normalizer="tenantIdnormalizer"
        :multiple="true"
        @input="treeSelectInput"
        @select="treeSelectChange"
        @deselect="treeSelectDeselect"
        @search-change="treeSelectSearch"
        @open="treeSelectOpen"
        @close="treeSelectClose"
      />
    </div>
  </div>
</template>
<script>
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import treeData from './data/tree'
export default {
  data() {
    return {
      value: null,
      options: []
    }
  },
  components: { Treeselect },
  mounted(){
    // 延迟模拟请求数据
    setTimeout(() => {
      this.options = treeData
      this.value = [111, 113] // 测试回显操作
    }, 300)
  },
  methods:{
    // 选中触发(第一次回显的时候会触发,清除值的时候会触发, value值为undefined) input事件用于v-model双向绑定组件更新父组件值
    treeSelectInput(value, instanceId) {
      console.log(value, 'input事件')
      console.log(this.value, 'this.value -- input') // 这个不需要 延迟
    },
    // 选中触发(清除值的时候不会触发)
    treeSelectChange(raw, instanceId) {
      console.log(raw, '当前的对象')
      setTimeout(() => { // 如果用到this.value 需要setTimeout延迟一下拿到最新的值
        console.log(this.value, 'this.value -- select')
      })
    },
    // 移除选项时触发 当设置multiple为true时生效  raw为当前移除的对象
    treeSelectDeselect(raw, instanceId) {
      console.log(raw, 'deselect-->>')
    },
    // 搜索
    treeSelectSearch(searchQuery, instanceId) {
      console.log(searchQuery, '当前搜索的值')
    },
    // 展开触发
    treeSelectOpen(instanceId) {
      console.log('展开了')
    },
    // 关闭触发
    treeSelectClose(value, instanceId) {
      console.log(value, '当前的value值')
    },
    // 字段默认 id label 用于规范化数据源
    tenantIdnormalizer(node, instanceId) {
      if (node.children && !node.children.length) {
        delete node.children
      }
      return {
        id: node.id,
        label: node.title,
        children: node.children
      }
    }
  }
}
</script>
<style scoped>
.main {
  width: 100%;
  height: 100%;
  padding: 60px 0 0 200px;
}

.main .tree {
  width: 240px;
  height: 40px;
}

::v-deep .vue-treeselect__label {
  color: #606266;
}
</style>

测试数据: 

export default [
  {
    "title": "系统管理",
    "parentId": 0,
    "id": 1,
    "children": [
      {
        "title": "菜单管理",
        "parentId": 1,
        "id": 11,
        "children": [
          {
            "title": "菜单新增",
            "parentId": 11,
            "id": 111
          },
          {
            "title": "菜单编辑",
            "parentId": 11,
            "id": 112
          },
          {
            "title": "菜单删除",
            "parentId": 11,
            "id": 113
          }
        ]
      },
      {
        "title": "角色管理",
        "parentId": 1,
        "id": 22,
        "children": [
          {
            "title": "角色编辑",
            "parentId": 22,
            "id": 222
          },
          {
            "title": "角色新增",
            "parentId": 22,
            "id": 221
          },
          {
            "title": "角色删除",
            "parentId": 22,
            "id": 223
          }
        ]
      }
    ]
  },
  {
    "title": "用户管理",
    "parentId": 0,
    "id": 33,
    "children": [
      {
        "title": "用户新增",
        "parentId": 33,
        "id": 331
      },
      {
        "title": "用户编辑",
        "parentId": 33,
        "id": 332
      },
      {
        "title": "用户删除",
        "parentId": 33,
        "id": 333
      }
    ]
  }
]

效果如下: 

@riophae/vue-treeselect,vue,前端,javascript,vue.js,javascript,前端 文章来源地址https://www.toymoban.com/news/detail-793459.html

到了这里,关于Vue通用下拉树组件@riophae/vue-treeselect的使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Vue Treeselect树形下拉框的使用

        昨天在做一个表单,里面有一项是以tree形式为选项的select框↓      于是乎,用到了vue中的treeselect组件,在此记录一下。 1、绑值, :value=“form.astdeptId”,主要绑的就是id或者code,通过id或code找到对应的label回显 2、options是数据源,正常调接口获取就行了 3、append-to-bo

    2024年02月06日
    浏览(34)
  • Element树型下拉框/vue2树型下拉框/TreeSelect/树型下拉

            今天小谭要给大家分享的是基于element ui 的下拉框和树型控件二次分装的树型下拉框,element plus新增了这一组件,但是对于还在使用vue2的我来说,就很不友好。组件可以实现单选和多选,以及其他常用功能,废话不多说,直接上效果图: 效果图如上,接下来实现代码

    2024年02月13日
    浏览(37)
  • [自定义 Vue 组件] 小尾巴下拉菜单组件(2.0) TailDropDown

    文章归档:https://www.yuque.com/u27599042/coding_star/kcoem6dgyn8drglb [自定义 Vue 组件] 下拉菜单(1.0) DropDownMenu:https://www.yuque.com/u27599042/coding_star/llltv52tchmatwg4 在 src 目录下,创建 constant 目录,在其中新建 tail_drop_down_constant.js 文件,在其中声明组件所依赖的常量 在 src 目录下,创建 sty

    2024年02月05日
    浏览(28)
  • Element+Vue实现动态表单(多个下拉框组件)

    表单的内容为巡检计划,巡检计划可以选择多个巡检点位,每个巡检点位可以选择多个设备和对应操作。 点击加号图标增加一个下拉框 减号图标删除对应下拉框 下拉框备选项目相同 点击设置动作按钮,弹出可编辑表格,可以为该巡检点位设置多个动作 表格每行内容可编 设

    2024年02月15日
    浏览(30)
  • 前端vue uni-app仿美团下拉框下拉筛选组件

    在前端Web开发中,下拉筛选功能是一种非常常见的交互方式,它可以帮助用户快速选择所需的选项。本文将介绍如何利用Vue.js和uni-app框架来实现一个高效的下拉筛选功能。通过使用这两个强大的前端框架,我们可以轻松地创建具有响应式用户操作的下拉筛选组件。 首先,我

    2024年02月09日
    浏览(33)
  • 基于vue+element ui实现下拉表格选择组件

    根据https://lolicode.gitee.io/scui-doc/demo/#/dashboard里的组件修改

    2024年02月16日
    浏览(43)
  • 通用vue组件化登录页面

    1.首先建立一个login文件夹,在里面建立对应的login.vue文件 2.设置登录页面的背景图,在App.vue文件中使用router-view进行展示登录组件 3.先给App.vue的div元素设置高度100%,之后在login.vue里面去设置背景图 这里注意怎么使login组件垂直水平居中的样式 1.首先建立一个cpns的文件夹,里

    2024年02月09日
    浏览(31)
  • 通用vue组件化展示列表数据

    1.首先先确定要展示的表格列名以及拿到所需要展示的数组数据 2.然后建立一个专门放el-table遍历的文件 3.在父组件中将数据列表数据存放在listData里面,然后传给子组件,子组件定义一个动态的列,通过遍历propList得到列名,然后也动态匹配prop,这样prop的值会去和listData进行匹

    2023年04月08日
    浏览(27)
  • Vue 中修改 Element 组件的 下拉菜单(Dropdown) 的样式

    今天在项目中碰到一个 UI 改造的需求,需要根据设计图把页面升级成 UI 设计师提供的设计图样式。 到最后页面改造完了,但是 UI 提供的下拉菜单样式全部是黑色半透明的,只能硬着头皮改了。 然后,就有了一下午的头脑风暴。 一开始,我是想着使用 /deep/ 来深度修改样式

    2024年01月17日
    浏览(44)
  • 记录--Vue3 封装 ECharts 通用组件

    配置文件这里就不再赘述,内容都是一样的,主打一个随用随取,按需导入。 chartRef :当前的 DOM 节点,即 ECharts 的容器; chartInstance :当前 DOM 节点挂载的 ECharts 实例,可用于调用实例上的方法,注册事件,自适应等; draw :用于绘制 ECharts 图表,本质是调用实例的 setOptio

    2024年02月09日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包