下拉框可筛选可树状多选组件

实际效果图片
下拉框可筛选可树状多选组件_第1张图片下拉框可筛选可树状多选组件_第2张图片

父页面

<el-form-item label="转发:" :label-width="formLabelWidth" class="formflex_item">
              <el-select ref="select" :clearable="true" @clear="clearSelect" @remove-tag="removeTagChange"  v-model="addForm.departmentList" placeholder="请选择" multiple collapse-tags style="width:220px">
                <el-popover
                  placement="right"
                  width="400"
                  trigger="click"
                  v-model="popover"
                >
                <div class="outer-container" @click="SelectVisible">
                  <div class="inner-container">
                      <div class="sel-input">
                        <el-input
                          placeholder="输入关键字进行过滤"
                          v-model="filterTextAll"
                          size="mini"
                          @click="intClick"
                          ref="inputRef"
                        >
                          <i slot="suffix" class="el-input__icon el-icon-search"></i>
                        </el-input>
                      </div>
                      <div class="repeatUserStyle">
                        <span>公司成员</span>
                      </div>
                      <!-- <el-option hidden v-for="item in branchList" :key="item.id" :value="item.id" :label="item.name+'——'+item.deptName" style="height: auto" /> -->
                      <el-tree
                        class="filter-tree"
                        :data="branchList2"
                        :props="defaultProps"
                        node-key="id"
                        show-checkbox
                        default-expand-all
                        :expand-on-click-node="true"
                        :filter-node-method="filterNodeAll"
                        @check-change="handleCheckChange"
                        @node-click="handleNodeClick"
                        @check="handleCheckClick"
                        ref="tree1"
                      >
                        <span slot-scope="{ data }">
                          <span>{{ data.deptName !== "全选" ? data.name+'——'+data.deptName : data.name}}</span>
                        </span>
                      </el-tree>
                    </div>
                  </div>
                  <div slot="reference" class="btnStyle">
                    <el-button size="mini">点击选择公司成员</el-button>
                  </div>
                </el-popover>

                <div class="sel-input">
                  <el-input
                    placeholder="输入关键字进行过滤"
                    v-model="filterText"
                    size="mini"
                  >
                    <i slot="suffix" class="el-input__icon el-icon-search"></i>
                  </el-input>
                </div>
                <div class="repeatUserStyle">
                  <span>常用转发人</span>
                  <el-tooltip class="item" effect="dark" content="点击添加常用转发人" placement="right">
                    <i class="el-icon-plus  cursor_pointer" @click="handleSetForwarderList"></i>
                  </el-tooltip>
                </div>
                <el-option hidden v-for="item in branchList" :key="item.id" :value="item.id" :label="item.name+'——'+item.deptName" style="height: auto" />
                  <el-tree
                    class="filter-tree"
                    :data="roleBoolean === true ? receiverList : forwardList2"
                    :props="defaultProps"
                    node-key="id"
                    show-checkbox
                    :default-expand-all="roleBoolean === true ? false : true"
                    :expand-on-click-node="true"
                    :filter-node-method="filterNode"
                    @check-change="handleCheckChange"
                    ref="tree"
                  >
                    <!-- :check-strictly="systemNodeFlag" -->
                  </el-tree>
              </el-select>
            </el-form-item>

代码部分

export default {
  data() {
    return {
	   	  filterText: "",
	      filterTextAll: "",
	      defaultProps: {
	        value: "id",
	        label: "name"
	      },
	      // 常用转发人数据
	      forwardList2: [{
	        id: "全选",
	        name: "全选",
	        string: "常用转发人",
	        deptName: "全选",
	        children: []
	      }],
	      branchList2: [{
	        id: "全选",
	        name: "全选",
	        string: "公司成员",
	        deptName: "全选",
	        children: []
	      }],
	      selectedData: [], // 选中的节点
			receiverList: [{
	        id: "全选",
	        name: "市局领导",
	        string: "常用转发人",
	        deptName: "全选",
	        children: []
	      },{
	        id: "全选",
	        name: "部门领导",
	        string: "常用转发人",
	        deptName: "全选",
	        children: []
	      },{
	        id: "全选",
	        name: "县局领导",
	        string: "常用转发人",
	        deptName: "全选",
	        children: []
	      },{
	        id: "全选",
	        name: "其他",
	        string: "常用转发人",
	        deptName: "全选",
	        children: []
	      }]
	    };
	},
	computed: {
   	 	...mapGetters(["permission", "userInfo"]),
  	},
  	watch: {
	    objId(newVal) {
	      console.log(this.objId);
	      this.fileParams.objectId = newVal;
	    },
	    //常用转发人,通过监听方式来代替focus(),
	    //this.$refs.tree.filter(val);触发el-tree的filterNode过滤属性
	    filterText(val) {
	      this.$refs.tree.filter(val);
	    },
	    //
	    filterTextAll(val) {
	      this.$refs.tree1.filter(val);
	    },
	    // 过滤
	    filterNode(value, data) {
	      console.log("filterNode",value)
	      if (!value) return true;
	      return data.name.indexOf(value) !== -1;
	    },
	    filterNodeAll(value, data) {
	      if (!value) return true;
	      let filterRes = data.name.indexOf(value) !== -1 || data.deptName.indexOf(value) !== -1;
	      return filterRes
	    },
	     // 点击tree组件的复选框节点触发
    handleCheckChange(data,checked) {
      if(checked === true) {
        if(data.id !== "全选") {
          this.addForm.departmentList.push(data.id)
          if(this.addForm.departmentList)
          this.SetArray(this.addForm.departmentList)
          this.$refs.tree.setChecked(data.id, true)
          this.$refs.tree1.setChecked(data.id, true)
        } else {
          // 解决过滤全选后的bug
          if(data.string === "常用转发人") {
            let checkKeys = this.$refs.tree.getCheckedKeys()
            checkKeys.forEach((i, n) => {
              let node = this.$refs.tree.getNode(i)
              if(!node.visible && node.checked) {
                this.$refs.tree.setChecked(i, false)
              }
            })
          } else {
            let checkKeys = this.$refs.tree1.getCheckedKeys()
            checkKeys.forEach((i, n) => {
              let node = this.$refs.tree1.getNode(i)
              if(!node.visible && node.checked) {
                this.$refs.tree1.setChecked(i, false)
              }
            })
          }
        }
        // this.$refs.tree.
      } else {
        if(this.addForm.departmentList.includes(data.id)) {
          this.addForm.departmentList.forEach((item, index, arr) => {
            if(item === data.id) {
              arr.splice(index, 1)
            }
          })
          this.$refs.tree.setChecked(data.id, false)
          this.$refs.tree1.setChecked(data.id, false)
        }
      }

      // if(data.id !== "全选") {
      //   this.$refs.select.toggleMenu()
      // } else {
      //   this.popover = false
      // }
    },
    // 下拉框清除项触发
    removeTagChange(val) {
      this.$refs.tree.setChecked(val, false)
      this.$refs.tree1.setChecked(val, false)
      this.$refs.select.blur()
      this.popover = false
    },
    // 点击删除全部
    clearSelect() {
      this.$refs.tree.setCheckedKeys([])
      this.$refs.tree1.setCheckedKeys([])
      this.addForm.departmentList = []
      this.popover = false
    },
    intClick() {
      this.$refs.inputRef.focus()
    },
    // 去重
    SetArray(arr) {
      this.addForm.departmentList = Array.from(new Set(arr))
    },
    // 添加常用转发人
    handleSetForwarderList() {
      this.dialogTableVisible = false
      this.popover = false
      this.$refs.select.blur()
      let id = this.$store.getters.userInfo.user_id
      this.formInline={
          companyId:"",
            deptId:"",
            realName:"",
            roleId:""
        };
        getForwarderList(id, this.formInline1).then(res => {
          this.forwarder.forwarderList = res.data.data;
          this.forwarder.forwarderModel = true;
          this.forwarder.userName = "";
          this.forwarder.id = id;
          this.forwarder.selectionList = [];
        })
      this.getCompanyDept()
    },
    getCompanyDept(){
      let vm = this
      companyOrDept(vm.formInline1.companyId).then(res =>{
        if(vm.formInline1.companyId === "" || vm.formInline1.companyId === null){
          vm.companyList = res.data.data;
          let col = {
            id: "",
            deptName: ""
          };
          vm.companyList.unshift(col);
          vm.deptList = [];
          vm.formInline1 = {
            companyId:"",
            deptId:"",
            realName: vm.formInline1.realName,
            roleId:vm.ids,
          }
        }else {
          vm.deptList = res.data.data;
          let col = {
            key: "",
            name: ""
          };
          vm.deptList.unshift(col);
        }
      });
    },
    //条件查询未添加到转发人员的列表
    searchForwarderList(){
      let that = this;
      getForwarderList(that.forwarder.id, that.formInline1).then(res => {
        that.forwarder.forwarderList = res.data.data;
      }).then(() => {
        //将已选择的数据选中
        for(var i=0;i<that.forwarder.forwarderList.length;i++){
          that.forwarder.selectionList.forEach(function(item){
            if(item.id === that.forwarder.forwarderList[i].id){
              that.$refs.table.toggleRowSelection(that.forwarder.forwarderList[i],true);
            }
          })
        }
      });
    },
    //添加转发人员
    addForwarder(){
      let that = this;
      //将已选人员id拼接
      var idList = "";
      that.forwarder.selectionList.forEach(function(item){
        idList = idList + item.id + ",";
      })
      addForwarder(that.forwarder.id, idList).then(res => {
        that.forwarder.forwarderModel = false;
        this.getForwardList()
        this.getCode()
        that.$message({
          type: "success",
          message: "操作成功!"
        });
      });
    },
    //selection状态修改(取消、选中)
    forwarderChange(selection, row){
      let that = this;
      //判断该数据是选中还是取消
      if(that.forwarder.selectionList == [] || that.forwarder.selectionList == undefined || that.forwarder.selectionList == null){
        that.forwarder.selectionList = [];
        that.forwarder.selectionList.push(row);
        return;
      }
      var i = 0;
      for(; i < that.forwarder.selectionList.length; i++){
        if(row.id == that.forwarder.selectionList[i].id){
          break;
        }
      }
      if(i == that.forwarder.selectionList.length){
        that.forwarder.selectionList.push(row);
      }else{
        if(that.forwarder.selectionList.length == 1){
          that.forwarder.selectionList = [];
        }else{
          that.forwarder.selectionList.splice(i, 1);
        }
      }
    },
    //全选未添加转发人员
    selectAll(selection){
      let that = this;
      if(selection != undefined){
        that.forwarder.selectionList = [];
        if(selection != []){
          that.forwarder.forwarderList.forEach(function(item){
            that.forwarder.selectionList.push(item);
          })
        }
      }
    },
    SelectVisible() {
      this.$refs.select.toggleMenu()
      this.$refs.inputRef.focus()
    },
    handleNodeClick() {
      this.$refs.select.toggleMenu()
    },
    handleCheckClick() {
      this.$refs.select.toggleMenu()
    },
    // 获取转发人权限
    getRole() {
      // 获取转发人的权限
      let userRoles = JSON.parse(localStorage.getItem("saber-userDetails")).content.roleAlias
      userRoles = userRoles.split(',')
      let roleArr = ['ROLE_COMPANY_BOSS','admin','ROLE_COMPANY_CS','ROLE_DEPART_BOSS']
      this.roleBoolean = userRoles.some(item => {
        return roleArr.includes(item) === true
      })
      if(this.roleBoolean === true) {
        this.getRolesList()
      }
    },
    getRolesList() {
      getReceiverList().then(res => {
        let obj = res.data.data
        this.receiverList[0].children = obj.市局领导
        this.receiverList[1].children = obj.部门负责人
        this.receiverList[2].children = obj.县局领导
        this.receiverList[3].children = obj.其他
      }).catch(() => {
        this.$message.error('获取常用转发人数据失败!')
      })
    }
  },
  },
	

拆分的组件:

<template>
  <div>
    <!-- 树形下拉框 -->
    <el-select style="width: 100%" ref="select" :multiple="multiple" :clearable="true" @remove-tag="handleRemoveTag" @clear="handleClear" v-model="companyId">
        <div class="sel-input">
            <el-input
            placeholder="输入关键字进行过滤"
            v-model="filterText"
            size="mini"
            >
                <i slot="suffix" class="el-input__icon el-icon-search"></i>
            </el-input>
        </div>
        <el-option v-if="mineStatusValue.length == 0" hidden key="id" :value="selectVal" :label="selectName"></el-option>
        <el-option v-else hidden v-for="(item, index) in mineStatusValue" :key="index" :label="parentLableVisble ? (item.parentLable + '——' + item[defaultProps.label]) : item[defaultProps.label]" :value="item[defaultProps.id]"></el-option>
        <el-tree
            :data="receiverList"
            :props="defaultProps"
            :node-key="defaultProps.id"
            :show-checkbox="multiple"
            :expand-on-click-node="true"
            :filter-node-method="filterNode"
            @check="handleCheckChange"
            @node-click="clickUnitTreeNode"
            ref="tree"
        >
        </el-tree>
    </el-select>
  </div>
</template>

<script>
export default {
    props: {
        // 树形结构数据
        receiverList: {
            type: Array,
            require: true,
            default: () => []
        },
        // 树形结构默认配置
        defaultProps: {
            type: Object,
            default: () => {
                return {
                    children: 'children',
                    label: 'label',
                    id: 'id'
                }
            }
        },
        // 是否多选
        multiple: {
            type: Boolean,
            default: () => {
                return false;
            }
        },
        // selectInput绑定的值
        companyId: {
            type: [Array, String, Number],
            default: ''
        },
        // 是否变成特殊结构:"XX"——"XX"
        parentLableVisble: {
            type: Boolean,
            default: false
        }
    },
    watch: {
        filterText(val) {
            this.$refs.tree.filter(val);
        }
    },
    data () {
        return {
            filterText: '',
            mineStatusValue: []
        }
    },
    methods: {
        // 树形结构数据过滤
        filterNode(value, data) {
            if (!value) return true;
            return data[this.defaultProps.label].indexOf(value) !== -1;
        },
        // 多选方法
        handleCheckChange(data) {
            if(!this.multiple) {
                return
            }
            let res = this.$refs.tree.getCheckedNodes(true)
            let key = this.$refs.tree.getCheckedKeys(true)
            this.mineStatusValue = res;
            // 全选 全选这里有个bug 记得在外面写方法是时候写一个去重方法
            if(data.children && data.children.length > 0) {
                data.children.forEach(items => {
                    let a = this.mineStatusValue.some(item => item.value === items.value)
                    if(a) {
                        this.$emit('handleCheckChange', key, items)
                        return
                    }
                    this.handleRemoveTag(items.value)
                })
                return
            }
            let a = this.mineStatusValue.some(item => item.value === data.value)
            if(a) {
                this.$emit('handleCheckChange', key, data)
                return
            }
            this.handleRemoveTag(data.value)
        },
        handleRemoveTag(value) {
            this.$refs.tree.setChecked(value, false);
            let res = this.$refs.tree.getCheckedNodes(true)
            this.mineStatusValue = res;
            this.$emit('handleRemoveTag', value)
        },
        handleClear() {
            if(this.multiple) {
                this.$refs.tree.setCheckedKeys([]);
            }
            this.mineStatusValue = []
            this.$emit('handleClear')
        },
        handleSelect(value) {
            this.$refs.tree.setCheckedKeys(value)
            let res = this.$refs.tree.getCheckedNodes(true)
            this.mineStatusValue = res;
        },
        // 单选方法
        clickUnitTreeNode(data) {
            if(this.multiple) {
                return
            }
            if(data && !data.children) {
                if(this.mineStatusValue.length === 0 || !(this.mineStatusValue.some(item => item.value === data.value))) {
                    this.mineStatusValue.push(data)
                }
                this.$emit('clickUnitTreeNode', data)
            }
        }
    }
}
</script>

<style lang="scss" scoped>
.sel-input {
    margin: 5px;
}
::v-deep.el-select .el-tag__close.el-icon-close {
    background-color: #C0C4CC;
    right: -7px;
    top: -6px;
}
</style>

你可能感兴趣的:(vue.js,前端,javascript)