vue element自定义下拉框

效果图:

<template>
      <el-select :size="size" ref="select" :disabled="disabledsl" :class="`lselectCom ${selectClassName}`" clearable v-model="selectVal" @clear="clearHandler" :placeholder="placeholder" :style="selStyle">
        <el-input :size="size" placeholder="" suffix-icon="el-icon-search" v-model="filterText"></el-input>
        <el-option :value="optionVal" style="height: auto">
          <el-tree :data="treeDataFin" 
            show-checkbox 
            default-expand-all
            node-key="label"
            ref="tree" 
            class="treeClass"
            highlight-current 
            :props="defaultProps"
            :filter-node-method="filterNode"
            @check-change="handleCheckChange"
          >
          </el-tree>
          <el-button :disabled='disabled' size="mini" type="primary" @click="okBtn">确定</el-button>
          <el-button size="mini" @click="clearHandler">清除</el-button>
        </el-option>
      </el-select>
</template>
<script>
export default {
  name:"L-select",
  props:{
    // checkedArr:this.temObj[column.property],
    defaultProps:{
      type:Object,
      default(){
        return {
          children: "children",
          label: "label"
        }
      }
    },
    treeData:{
      type:Array,
      // required: true,
      default(){
        return []
      }
    },
    size:{
      type:String,
      default(){
        return "mini"
      }
    },
    selStyle:{
      type:String,
      default(){
        return ""
      }
    },
    placeholder:{
      type:String,
      default(){
        return "请选择"
      }
    },
    pIndex:{
      type:Number,
      default(){
        return 1
      }
    },
    //表格列
    column:{
      type:Object,
      default(){
        return {}
      }
    },
   //下拉框输入框内是否展示筛选后数据
    showVal:{
      type:Boolean,
      default(){
        return false
      }
    },
    //默认全选数组
    checkedArr:{
      type:Array,
      default(){
        return []
      }
    },
    runokBtn:{
      type:Boolean,
      default(){
        return false
      }
    },
   //筛选前后图标
    selectClassName:{
      type:String,
      default(){
        return "selectBefore"
      }
    },
   //是否禁用
    disabledsl:{
      type:Boolean,
      default(){
        return false
      }
    },
    //初始化数据备份重置
    initSelectData:{
      type:Array,
      default(){
        return []
      }
    }

  },
  data() {
    return {
      temObj:[],
      selectVal:"",
      filterText:"",
      searchVarValue:[],
      optionVal:"",
      treeDataFin:[],
      disabled:false,
      arrFin:[]
    };
  },
  mounted(){
    
  },
  watch: {
  //数据过滤
    filterText(val) {
      this.arrFin=[]
      this.$refs.tree.filter(val);
    },
   //格式化数据
    treeData:{
      handler(newval){
        // console.log(newval,"990909090")
        let arr = [];
        newval.forEach((item,index)=>{
          arr.push({label:item,id:index})
        })
        // arr.push({label:"",id:10000})
        this.treeDataFin = [{label:"全部",children:arr}]
      },
      immediate:true
    },
    checkedArr:{
      handler(newval){
      // console.log(newval,"909090988888880")
        this.$nextTick(()=>{
          // console.log(newval,"cccccccc")
          // this.$refs.tree.filter(newval);
          this.$refs.tree.setCheckedKeys(newval)
        })
      },
      immediate:true
    },
    runokBtn:{
      handler(newval){
        if(newval){
          setTimeout(()=>{
            this.selectVal = this.searchVarValue.join(",")
            this.$emit("selectVal",this.searchVarValue,this.pIndex,this.column,this.placeholder)
          },300)
        }
      },
      immediate:true
    }
  },
  components: {

  },
  methods:{
    okBtn(){
        this.filterText=""
        if(!this.showVal)this.optionVal = this.searchVarValue.join(",")
        this.$emit("selectVal",this.searchVarValue,this.pIndex,this.column,this.placeholder)
    },
    clearHandler(){
      this.searchVarValue=this.initSelectData
      // this.optionVal=""
      this.filterText=""
      this.$nextTick(() => {
        this.$refs.tree.setCheckedKeys(["全部"])
        setTimeout(()=>{
          // console.log(this.searchVarValue,"this.searchVarValuethis.searchVarValuethis.searchVarValuethis.searchVarValue")
          this.$emit("selectVal",this.initSelectData,this.pIndex,this.column,this.placeholder,"clear")
        })
      });
    },
    filterNode(value, data) {
      // this.arrFin=[]
      // this.$refs.tree.setCheckedKeys([])
      // console.log(value,this.searchVarValue,"-------------")
        let arr  =[]
        if (!value) {
          this.arrFin=[]
          // if(this.searchVarValue.length==0){
            this.$refs.tree.setCheckedKeys(["全部"])
          // }
          return true
        };
        if(data.label.toLowerCase().indexOf(value.toLowerCase())!==-1){
          this.arrFin.push(data.label)
          this.$refs.tree.setCheckedKeys(this.arrFin)
          return true;
        }
      
    },
    handleCheckChange(data, checked, node) {
        let res = this.$refs.tree.getCheckedNodes(true, true); 
        // if (checked) {
        //     this.$refs.tree.setCheckedNodes([data]);
        // }
        let arrLabel = [];
        res.forEach(item => {
            arrLabel.push(item[this.defaultProps.label]);
        });
        this.searchVarValue = arrLabel
        // this.selectVal = arrLabel;
        if(arrLabel.length==0){
          this.disabled=true
        }else{
          this.disabled=false
        }
    },
  }

};
</script>

<style lang="less">
.lselectCom{
  .el-input__inner:first-child{
    background-color:#fff;
    // border:0;
    padding-left:5px;
    
  }
  input::-webkit-input-placeholder{
      color:#565555;
      font-size: 14px;
      text-align:center
  }
  input::-moz-placeholder{   /* Mozilla Firefox 19+ */
      color:#565555;
      font-size: 14px;
      text-align:center
  }
  input:-moz-placeholder{    /* Mozilla Firefox 4 to 18 */
      color:#565555;
      font-size: 14px;
      text-align:center
  }
  input:-ms-input-placeholder{  /* Internet Explorer 10-11 */ 
      color:#565555;
      font-size: 14px;
      text-align:center
  }
  .el-input .el-select__caret.is-reverse{
      transform: rotateZ(180deg)!important
  }
  .el-input .el-select__caret{
    transform: rotateZ(0)!important
  }
}
  .selectAfter .el-icon-arrow-up:before{
      content:"e87a";
      font-family: "iconfont";
      color:#A9A9A9;
      font-size: 10px;
      // margin-right:12px
    }

  .selectBefore .el-icon-arrow-up:before{
      content:"e65a";
      font-family: "iconfont";
      color:#A9A9A9;
      font-size: 22px;
      // margin-right:12px
    }
.el-select-dropdown__list{
  padding:6px 10px;
  .el-input{
    margin:10px 0
  }
}
.el-select-dropdown__item{
  padding:0;
  text-align:center
}
.el-select-dropdown__item.hover, .el-select-dropdown__item:hover{
  background-color:#fff
}
.treeClass{
  border:1px solid #eee;
  max-height:170px;
  overflow:auto
}
  .el-button--primary.is-disabled{
    box-shadow: 0 0 0 0
  }
  .el-select-dropdown__wrap.el-scrollbar__wrap{
    margin-bottom:0!important
  }
</style>

父组件

原文地址:https://www.cnblogs.com/FormerWhite/p/14265644.html