el-select+el-tree仿TreeSelect组件

摘要:
˂! value:[value]“:默认选中的键=”(多个&&Array.isArray(value))?
<!--el-select+el-tree -->
<template>
  <el-select
    ref="select"
    popper-class="TREE_SELECT_POPPER"
    :value="showLabel"
    :size="size"
    :placeholder="placeholder"
    :clearable="clearable"
    :disabled="disabled"
    :filterable="filterable"
    :filter-method="selectFilter"
    @visible-change="visibleChange"
    @focus="selectFocus"
    @clear="emitVal"
  >
    <el-option class="option_li" :value="showLabel" :label="showLabel" :style="{height: optionHeight+'px'}">
      <el-scrollbar class="option_li_scroll">
        <el-tree
          ref="tree"
          :accordion="accordion"
          :data="options"
          :props="props"
          :node-key="props.value"
          :show-checkbox="multiple"
          :default-expanded-keys="(multiple && Array.isArray(value)) ? value : [value]"
          :default-checked-keys="(multiple && Array.isArray(value)) ? value : []"
          :expand-on-click-node="false"
          :check-strictly="checkStrictly"
          :filter-node-method="treeFilter"
          @node-click="nodeClick"
          @check="nodeCheck"
        />
      </el-scrollbar>
    </el-option>
  </el-select>
</template>
<script>
import pinyinMatch from 'pinyin-match'
export default {
  name: 'TreeSelect',
  props: {
    props: { // 配置项
      type: Object,
      default() {
        return {
          value: 'value',
          label: 'label',
          children: 'children'
        }
      }
    },
    options: { // 选项列表数据
      type: Array,
      default() {
        return []
      }
    },
    value: { // 绑定值
      type: [String, Number, Array],
      default: ''
    },
    accordion: { // 是否每次只展开一个同级树节点
      type: Boolean,
      default: false
    },
    size: {
      type: String,
      default: ''
    },
    multiple: { // 是否可多选
      type: Boolean,
      default: false
    },
    filterable: { // 是否可搜索
      type: Boolean,
      default: true
    },
    clearable: { // 是否可清空
      type: Boolean,
      default: true
    },
    disabled: { // 是否禁用
      type: Boolean,
      default: false
    },
    placeholder: {
      type: String,
      default: ''
    },
    checkStrictly: { // 父子是否不互相关联
      type: Boolean,
      default: false
    },
    lastLevel: {
      type: String,
      default: ''
    },
    infoError: {
      type: String,
      default: ''
    },
    popHeight: {
      type: [String, Number],
      default: 247
    }
  },
  data() {
    return {
      optionHeight: 247
    }
  },
  computed: {
    showLabel() {
      let label = ''
      const value = this.value
      if (this.multiple) { // 多选
        if (Array.isArray(value) && value.length > 0) {
          const labelArr = []
          value.forEach(value => {
            labelArr.push(this.queryTree(this.options, value))
          })
          label = labelArr.join(',')
        }
      } else { // 单选
        if (value) {
          label = this.queryTree(this.options, value)
        }
      }
      return label
    }
  },
  methods: {
    // 搜索树状数据中的 ID,获取label
    queryTree(tree, id) {
      let stark = []
      stark = stark.concat(tree)
      let label = ''
      while (stark.length) {
        const temp = stark.shift()
        if (temp[this.props.children]) {
          stark = stark.concat(temp[this.props.children])
        }
        if (temp[this.props.value] === id) {
          label = temp[this.props.label]
        }
      }
      return label
    },
    // 提交值
    emitVal(val) {
      if (!val) {
        val = this.multiple ? [] : ''
      }
      this.$emit('input', val)
    },
    // select框获得焦点
    selectFocus() {
      this.$refs.tree.filter('')
      this.$emit('on-focus')
    },
    // select option过滤
    selectFilter(label) {
      this.$refs.tree.filter(label)
      return true
    },
    // 树过滤方法
    treeFilter(query, data) {
      if (!query) {
        return true
      } else {
        const labelArray = query.split(',')
        // 拼配全有科室 误删
        // return labelArray.some(value => {
        //   return value && data[this.props.label].includes(value)
        // })
        return labelArray.some(value => {
          return value && pinyinMatch.match(data[this.props.label], value)
        })
      }
    },
    // 下拉框出现/隐藏
    visibleChange(show) {
      if (show) {
        this.$nextTick(() => {
          const tree_H = this.$refs.tree.$el.clientHeight
          if (tree_H < this.optionHeight) {
            this.optionHeight = this.popHeight
          }
        })
      }
    },
    // 点击节点
    nodeClick(node) {
      if (!this.multiple) {
        if (node[this.lastLevel] === 0) {
          this.$message.error(this.infoError)
          this.emitVal()
          return false
        }
        this.emitVal(node[this.props.value])
        this.$emit('info', node)
        this.$refs.select.blur() // 使select失去焦点 隐藏下拉框
      }
    },
    // 点击复选框
    nodeCheck(node, data) {
      this.emitVal(data.checkedKeys)
    }
  }
}
</script>
<style lang="scss" type="text/scss">
  .TREE_SELECT_POPPER>.el-scrollbar {
    >.el-scrollbar__bar.is-vertical {
      right:10px;
      display: none;
    }
  }
  .TREE_SELECT_POPPER .el-select-dropdown__item{
    background: #fff;
  }
</style>
<style scoped lang="scss" type="text/scss">
  .el-select-dropdown__item {
    height: auto;
    padding: 0;
    &.selected {
      font-weight: normal;
    }
  }
  .el-tree /deep/ .el-tree-node__content {
    height: 34px !important;
    padding: 0 10px 0 0;
  }
  .option_li {
    padding: 0;
    background-color: #fff;
    &.selected {
      font-weight: normal;
    }
    .option_li_scroll {
      height: 100%;
      /deep/ .el-scrollbar__wrap{
        overflow-x: hidden;
      }
    }
  }
  .el-tree {
    box-sizing: border-box;
    padding: 0 12px;
  }
</style>
 
使用
<tree-select
      v-model="departValue"
      :options="departmentList"
      :props="{
        label: 'treedatacodeandname',
        value: treeValue,
        children: 'childList'
      }"
      :disabled="disabled"
      filterable
      last-level="blnisdetail"
      info-error="请选择末级"
      @input="onChange"
      @info="onChangeInfo"
    />

免责声明:文章转载自《el-select+el-tree仿TreeSelect组件》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇mysql8中窗口函数使用AspNetPager分页,跳转后,返回到当前分页页面 dodo下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

mysql 查询优化 ~explain解读之select_type的解读

一 简介:今天咱们来聊聊explain的select_type 二 类型  (1)SIMPLE    简单的SELECT语句(不包括UNION操作或子查询操作)  (2)PRIMARY/UNION   PRIMARY:查询中最外层的SELECT(如两表做UNION或者存在子查询的外层的表操作为PRIMARY,内层的操作为UNION)   UNION:U...

SQLServer数据库(二)

数据库设计:就是将数据库中的数据库实体及这些数据库实体之间的关系,进行规划和结构化的过程。 项目开发过程: 需求分析 概要设计 详细设计 代码编写 运行测试 打包发行 数据库的系统分析基本步骤:收集信息、标识实体、标识每个实体需要存储的详细信息、标识实体之间的关系。 实体,就是指现实世界中具有区分其它事物的特征或属性,并与其他实体有联系的实体。实体一般是名...

MySQL取每组的前N条记录

一、对分组的记录取前N条记录:例子:取前 2条最大(小)的记录 1 1.用子查询: 2 SELECT * FROM right2 a WHERE 2> 3 (SELECT COUNT(*) FROM right2 b WHERE b.id=a.id AND b.account>a.account) 4 ORDER BY a.id,a....

第4章 数据库安全性 | 数据库知识点整理

第4章 数据库安全性 了解 计算机系统安全性问题 数据库安全性问题 威胁数据库安全性因素 掌握 TCSEC和CC标准的主要内容 C2级DBMS、B1级DBMS的主要特征DBMS提供的安全措施 用户身份鉴别、自主存取控制、强制存取控制技术 视图技术和审计技术 数据加密存储和加密传输 使用SQL语言中的GRANT语句和REVOKE语句来实现自主存...

Oracle WIHT AS 用法

1、with table as 相当于建个临时表(用于一个语句中某些中间结果放在临时表空间的SQL语句),Oracle 9i 新增WITH语法,可以将查询中的子查询命名,放到SELECT语句的最前面。语法就是with tempname as (select ....)select ...例子:with t as (select * from emp whe...

oracle创建用户、授予权限及删除用户

创建用户 oracle对表空间 USERS 无权限 alter user 用户名 quota unlimited on users; //创建临时表空间 create temporary tablespace test_temp tempfile 'E:/oracle/product/10.2.0/oradata/testserver/test_tem...