美文网首页
基于Element-UI组件改造的树形选择器

基于Element-UI组件改造的树形选择器

作者: 前端新阳 | 来源:发表于2019-11-26 11:12 被阅读0次
  1. 安装 element-ui 依赖,按需依赖,性能更优
npm i element-ui -S
  1. main.js 引入依赖,加入如下代码:
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
  1. 注册局部组件 SelectTree.vue,代码如下:
<template>
  <el-select :value="valueTitle" :clearable="clearable" @clear="clearHandle">
    <el-option :value="valueTitle" :label="valueTitle" class="options">
      <el-tree  
        id="tree-option"
        ref="selectTree"
        :accordion="accordion"
        :data="options"
        :props="props"
        :node-key="props.value"    
        :default-expanded-keys="defaultExpandedKey"
        @node-click="handleNodeClick">
      </el-tree>
    </el-option>
  </el-select>
</template>

<script>
export default {
  name: "el-tree-select",
  props:{
    // 配置项
    props:{
      type: Object,
      default: {
          value:'id',             // ID字段名
          label: 'title',         // 显示名称
          children: 'children'    // 子级字段名
        }
    },
    
    // 选项列表数据(树形结构的对象数组)
    options:{ type: Array, default: [] },
    
    // 初始值
    value:{ type: Number, default: null },
    
    // 可清空选项
    clearable:{ type:Boolean, default: true },
    
    // 自动收起
    accordion:{ type:Boolean, default: false }
  },
  data() {
    return {
      valueId: null,
      valueTitle:'',
      defaultExpandedKey:[]    
    }
  },
  mounted(){
    this.valueId = this.value,    // 初始值
    this.initHandle()
  },
  methods: {
    // 初始化值
    initHandle(){
      if(this.valueId){
        this.valueTitle = this.$refs.selectTree.getNode(this.valueId).data[this.props.label]     // 初始化显示
        this.$refs.selectTree.setCurrentKey(this.valueId)       // 设置默认选中
        this.defaultExpandedKey = [this.valueId]      // 设置默认展开
      } 
      this.initScroll()
    },
    // 初始化滚动条
    initScroll(){
      this.$nextTick(()=>{
        let scrollWrap = document.querySelectorAll('.el-scrollbar .el-select-dropdown__wrap')[0]
        let scrollBar = document.querySelectorAll('.el-scrollbar .el-scrollbar__bar')
        scrollWrap.style.cssText = 'margin: 0px; max-height: none; overflow: hidden;'
        scrollBar.forEach(ele => ele.style.width = 0)
      })
    },
    // 切换选项
    handleNodeClick(node){
      this.valueTitle = node[this.props.label]
      this.valueId = node[this.props.value]
      this.$emit('getValue',this.valueId)
      this.defaultExpandedKey = []
    },
    // 清除选中
    clearHandle(){
      this.valueTitle = ''
      this.valueId = null
      this.defaultExpandedKey = []
      this.clearSelected()
      this.$emit('getValue',null)
    },
    // 清空选中样式
    clearSelected(){
      let allNode = document.querySelectorAll('#tree-option .el-tree-node')
      allNode.forEach((element)=>element.classList.remove('is-current'))
    }
  },
  watch: {
    value(){
      this.valueId = this.value
      this.initHandle()
    }
  },
}
</script>

<style scoped>
  .el-scrollbar .el-scrollbar__view .el-select-dropdown__item{
    height: auto;
    max-height: 274px;
    padding: 0;
    overflow: hidden;
    overflow-y: auto;
  }
  .el-select-dropdown__item.selected{
    font-weight: normal;
  }
  ul li >>>.el-tree .el-tree-node__content{
    height:auto;
    padding: 0 20px;
  }
  .el-tree-node__label{
    font-weight: normal;
  }
  .el-tree >>>.is-current .el-tree-node__label{
    color: #409EFF;
    font-weight: 700;
  }
  .el-tree >>>.is-current .el-tree-node__children .el-tree-node__label{
    color:#606266;
    font-weight: normal;
  }
</style>
  1. 使用到的地方,代码如下:
<template>
  <div>
    <h1>{{`基于Element-UI组件改造的树形选择器`}}</h1>
    <!-- 调用树形下拉框组件 -->
    <SelectTree 
      :props="props"
      :options="optionData"
      :value="valueId"
      :clearable="isClearable"
      :accordion="isAccordion"
      @getValue="getValue($event)"/>
  </div>
</template>

<script>
import SelectTree from "@/components/SelectTree.vue";
export default {
  components: {
    SelectTree
  },
  data() {
    return { 
      isClearable:true,      // 可清空(可选)
      isAccordion:true,      // 可收起(可选)
      valueId:20,            // 初始ID(可选)
      props:{                // 配置项(必选)
        value: 'id',
        label: 'name',
        children: 'children',
        // disabled:true
      },
      // 选项列表(必选)
      list:[
        {id:1,parentId:0,name:"一级菜单A",rank:1},
          {id:2,parentId:0,name:"一级菜单B",rank:1},
          {id:3,parentId:0,name:"一级菜单C",rank:1},
          {id:4,parentId:1,name:"二级菜单A-A",rank:2},
          {id:5,parentId:1,name:"二级菜单A-B",rank:2},
          {id:6,parentId:2,name:"二级菜单B-A",rank:2},
          {id:7,parentId:4,name:"三级菜单A-A-A",rank:3},
          {id:8,parentId:7,name:"四级菜单A-A-A-A",rank:4},
          {id:9,parentId:8,name:"五级菜单A-A-A-A-A",rank:5},
          {id:10,parentId:9,name:"六级菜单A-A-A-A-A-A",rank:6},
          {id:11,parentId:10,name:"七级菜单A-A-A-A-A-A-A",rank:7},
          {id:12,parentId:11,name:"八级菜单A-A-A-A-A-A-A-A",rank:8},
          {id:13,parentId:12,name:"九级菜单A-A-A-A-A-A-A-A-A",rank:9},
          {id:14,parentId:13,name:"十级菜单A-A-A-A-A-A-A-A-A-A",rank:10},
          {id:15,parentId:0,name:"一级菜单C",rank:1},
          {id:16,parentId:0,name:"一级菜单C",rank:1},
          {id:17,parentId:0,name:"一级菜单C",rank:1},
          {id:18,parentId:0,name:"一级菜单C",rank:1},
          {id:19,parentId:0,name:"一级菜单C",rank:1},
          {id:20,parentId:0,name:"一级菜单C",rank:1},
          {id:21,parentId:0,name:"一级菜单C",rank:1},
          {id:22,parentId:0,name:"一级菜单C",rank:1},
          {id:23,parentId:0,name:"一级菜单C",rank:1},
          {id:24,parentId:0,name:"一级菜单C",rank:1},
          {id:25,parentId:0,name:"一级菜单C",rank:1},
          {id:26,parentId:0,name:"一级菜单C",rank:1},
          {id:27,parentId:0,name:"一级菜单C",rank:1},
          {id:28,parentId:0,name:"一级菜单C",rank:1},
          {id:29,parentId:0,name:"一级菜单C",rank:1},
          {id:30,parentId:0,name:"一级菜单C",rank:1},
          {id:31,parentId:0,name:"一级菜单C",rank:1},
          {id:32,parentId:0,name:"一级菜单C",rank:1},
          {id:33,parentId:0,name:"一级菜单C",rank:1},
          {id:34,parentId:0,name:"一级菜单C",rank:1},
          {id:35,parentId:0,name:"一级菜单C",rank:1},
          {id:36,parentId:0,name:"一级菜单C",rank:1},
          {id:37,parentId:0,name:"一级菜单C",rank:1},
          {id:38,parentId:0,name:"一级菜单C",rank:1},
          {id:39,parentId:0,name:"一级菜单C",rank:1},
          {id:40,parentId:0,name:"一级菜单end",rank:1}
      ]
    };
  },
  computed:{
    /* 转树形数据 */
    optionData(){
      let cloneData = JSON.parse(JSON.stringify(this.list))      // 对源数据深度克隆
      return  cloneData.filter(father=>{                      // 循环所有项,并添加children属性
          let branchArr = cloneData.filter(child=>father.id == child.parentId);       // 返回每一项的子级数组
          branchArr.length>0 ? father.children=branchArr : ''   //给父级添加一个children属性,并赋值
          return father.parentId==0;      //返回第一层
      });
    }
  },
  methods:{
    // 取值
    getValue(value){
      this.valueId = value
      console.log(this.valueId);
    }
  }
};
</script>
  1. 效果如下:
树形选择器

相关文章

网友评论

      本文标题:基于Element-UI组件改造的树形选择器

      本文链接:https://www.haomeiwen.com/subject/volewctx.html