迷幻需求之element-ui下拉复选框

  • 概述

      注入树形数据加载出下拉checkbox-group,数据是比下拉树看着要清晰一点

  • 效果

  • 组件代码
<template>
  <div class="form-check-select-main">
    <el-select v-model="inputData"
               :style="selectStyle"
               :popper-append-to-body="false"
               @remove-tag="removeTag"
               multiple
               placeholder="请选择"
               @change="selectChange()"
               @visible-change="visibleChange"
               :size="selectParam.size">
      <el-option :key="0" value="" :style="formCheckSelectOption" ref="formOption">
        <el-form>
          <div v-for="(node) in treeData" :key="node[checkBoxParam.valueName]" class="form-check-select-group">
            <el-row :style="groupRowStyle">
              <el-checkbox :indeterminate="isIndeterminate[node[checkBoxParam.valueName]]"
                           v-model="nodeCheckAll[node[checkBoxParam.valueName]]"
                           @change="(val)=>{checkBoxCheckAllChange(val,node)}"
                           :label="node[checkBoxParam.valueName]"
                           border
              > {{ node[checkBoxParam.lableName] }}
              </el-checkbox>
              <div style="margin: 15px 0;"></div>
              <el-checkbox-group v-model="checkedNodes" @change="checkBoxCheckChange">
                <el-col
                    v-for="child in node[checkBoxParam.childName]"
                    :key="child[checkBoxParam.valueName]"
                    :span="itemSpan">
                  <el-checkbox
                      :style="checkboxStyle"
                      @change="(val)=>{checkNode(val,child)}"
                      :label="child[checkBoxParam.valueName]"
                      border>
                    {{ child[checkBoxParam.lableName] }}
                  </el-checkbox>
                </el-col>
              </el-checkbox-group>
            </el-row>
            <hr style="FILTER: alpha(opacity = 100,finishopacity=0,style = 3);margin-top: 10px" width="100%"
                color=#987cb9 SIZE=3/>
          </div>
        </el-form>
      </el-option>
    </el-select>
  </div>
</template>

<script scoped>
export default {
  name: "FormCheckSelect",
  props: {
    itemSpan: {
      type: Number,
      default: 4
    },
    with: {
      type: Number,
      default: document.body.scrollWidth - 84
    },
    useParentName: {
      type: Boolean,
      default: false
    },
    defaultInputValue: {
      type: Array,
    },
    defaultInputData: {
      type: Array,
    },
    selectParam: {
      type: Object,
    },
    checkBoxParam: {
      type: Object,
      required: true,
    },
    size: {
      type: String,
      default: 'small'
    },
    treeData: {
      type: Array,
      required: true,
    },
  },
  components: {},
  computed: {},
  data() {
    return {
      formCheckSelectOption: {
        'height': 'auto !important',
        'line-height': 'normal',
        'width': this.with + 'px'
      },
      selectStyle: {
        'width': this.with + 'px'
      },
      valueManage: {
        groupData: []
      },
      inputValue: [],
      inputData: [],
      checkboxStyle: {
        'margin-top': '5px'
      },
      groupRowStyle: {
        'margin-top': '20px'
      },
      checkedNodes: [],
      nodeCheckAll: {},
      isIndeterminate: {}
    }
  },
  methods: {
    /**
     *  arr是否包含brr
     * @param arr
     * @param brr
     */
    opClick() {

    },
    isArrContain(arr, brr) {
      return brr.every(val => {
        return arr.includes(val);
      })
    },
    arrDelete(arr, element) {
      let index = arr.indexOf(element);
      arr.splice(index, 1);
      return arr;
    },
    arrAdd(arr, element) {
      if (!element) {
        return arr;
      }
      if (arr.includes(element)) {
        return arr;
      }
      arr.push(element);
      return arr;
    },
    updateValue(value, lable, isAdd) {
      if (isAdd) {
        this.arrAdd(this.inputValue, value);
        this.arrAdd(this.inputData, lable);
      } else {
        this.arrDelete(this.inputValue, value);
        this.arrDelete(this.inputData, lable);
      }
    },
    checkNode(isAdd, node) {
      let id = node[this.checkBoxParam.valueName];
      let lable = node[this.checkBoxParam.lableName];
      let pId = node[this.checkBoxParam.parentValueName];
      this.updateValue(id, lable, isAdd);
      this.calculationGroup(this.inputValue);
      this.calculationIndeterminate(pId);
    },
    /**
     * 计算指定id的父选项 勾选框样式
     */
    calculationIndeterminate(pId) {
      for (let groupDatum of this.valueManage.groupData) {
        if (groupDatum.rootValue === pId) {
          //当选中值中有这组的成员并且不完全包含这组成员时
          this.isIndeterminate[pId] = this.inputValue.some(p => {
                return groupDatum.valueArr.includes(p)
              })
              && (!this.isArrContain(this.inputValue, groupDatum.valueArr));
          break;
        }
      }
    },
    selectChange() {
      return false;
    },
    visibleChange(val) {
      if (val) {
        //修改样式
      }
    },
    checkBoxCheckChange(val) {

    },
    checkBoxCheckAllChange(val, node) {
      for (let i = 0; i < node.children.length; i++) {
        let value = node.children[i][this.checkBoxParam.valueName];
        let lable = node.children[i][this.checkBoxParam.lableName];
        this.updateValue(value, lable, val);
      }
      this.calculationGroup(this.inputValue);
      this.isIndeterminate[node[this.checkBoxParam.valueName]] = false;
    },
    initCalculationData() {
      if (!!this.treeData && this.treeData.length > 0) {
        for (let i = 0; i < this.treeData.length; i++) {
          let rootNode = this.treeData[i];
          let rootNodeValue = rootNode[this.checkBoxParam.valueName];
          let rootNodeLable = rootNode[this.checkBoxParam.lableName];
          //根据注入数据 生成全选对象
          let groupData = {
            rootValue: rootNodeValue,
            rootLable: rootNodeLable,
            valueArr: [],
            lableArr: []
          }
          for (let i = 0; i < rootNode.children.length; i++) {
            let node = rootNode.children[i];
            let value = node[this.checkBoxParam.valueName];
            let lable = node[this.checkBoxParam.lableName];
            groupData.valueArr.push(value);
            groupData.lableArr.push(lable);
          }
          this.valueManage.groupData.push(groupData);
        }
      }
    },
    init() {
      this.initCalculationData();
      //初始化默认选中
      this.inputData = !!this.defaultInputData ? this.defaultInputData : [];
      this.inputValue = !!this.defaultInputValue ? this.defaultInputValue : [];
      //计算分组
      this.calculationGroup(this.inputValue);
    },
    getSelectData() {
      return this.inputData;
    },
    getSelectValue() {
      return this.inputValue;
    },
    getValueByLable(lable) {
      for (let group of this.valueManage.groupData) {
        for (let grouplable of group.lableArr) {
          if (grouplable === lable) {
            return group.valueArr[group.lableArr.indexOf(grouplable)];
          }
        }
      }
      return "";
    },
    removeTag(val) {
      if (!this.valueManage.inputData) {
        return;
      }
      let removeIndex = this.valueManage.inputValue.indexOf(this.getValueByLable(val));
      let groupArr = this.valueManage.groupData.filter(p => {
        return p.rootLable === val
      });
      if (groupArr.length > 0) {
        let groupData = groupArr[0];
        this.inputValue = this.inputValue.filter(p => {
          return !groupData.valueArr.includes(p);
        });
      } else if (removeIndex >= 0) {
        this.inputValue.splice(removeIndex, 1);
      }
      this.calculationGroup(this.inputValue);
    },
    calculationGroup(inputNewValue) {
      if (this.useParentName) {
        for (let i = 0; i < this.valueManage.groupData.length; i++) {
          let childrenValueArr = this.valueManage.groupData[i].valueArr;
          let rootLable = this.valueManage.groupData[i].rootLable;
          let rootValue = this.valueManage.groupData[i].rootValue;
          let isExitGroupLable = this.inputData.includes(rootLable);
          //选中值是否包含所有组中的元素
          if (this.isArrContain(inputNewValue, childrenValueArr)) {
            this.nodeCheckAll[rootValue] = true
            if (!isExitGroupLable) {
              this.inputData = this.inputData.filter(o => {
                return this.valueManage.groupData[i].lableArr.indexOf(o) < 0
              })
              if (!this.valueManage.groupData[i].rootLable) {
                return;
              }
              this.inputData.push(this.valueManage.groupData[i].rootLable);
            }
          } else {
            this.calculationIndeterminate(rootValue)
            this.nodeCheckAll[rootValue] = false
            if (isExitGroupLable) {
              this.arrDelete(this.inputData, rootLable);
            }
            for (let value of inputNewValue) {
              let index = this.valueManage.groupData[i].valueArr.indexOf(value);
              if (index >= 0) {
                this.arrAdd(this.inputData, this.valueManage.groupData[i].lableArr[index]);
              }
            }
          }
        }
      }
    },
  },
  mounted() {
  },
  created() {
    this.init()
  },
  watch: {
    inputValue(newValue) {
      this.valueManage.inputValue = newValue
      this.checkedNodes = newValue;
    },
    inputData(newValue) {
      if (newValue.some(d => {
        return (d === undefined || d === "");
      })) {
        this.inputData = newValue.filter(d => {
          return !!d;
        })
      }
      this.valueManage.inputData = newValue
    }
  }
}
</script>

<style type="text/css">

</style>
  • 调用代码
<template>
  <div id="app">
    <el-button type="primary" @click="getValue">获取值</el-button>
    <el-button type="primary" @click="getLable">获取名</el-button>
    <formcheckselect
        ref="checkSelect"
        :default-input-data="defaultLable"
        :default-input-value="defaultValue"
        :tree-data="treeData"
        :check-box-param="checkBoxParam"
        :select-param="selectParam"
        :useParentName=true
    />
  </div>
</template>

<script>
import formcheckselect from './components/common/formcheckselect'

export default {
  name: 'app',
  data() {
    return {

      selectParam: {
        size: 'small',
      },
      checkBoxParam: {
        lableName: 'name',
        valueName: 'company_id',
        parentValueName:'parent_company_id',
        childName: 'children'
      },
      defaultValue: [],
      defaultLable: [],
      treeData: [{
        "company_id": "1",
        "parent_company_id": "2",
        "name": "局属事业单位",
        "simple_name": null,
        "code": null,
        "owner": null,
        "qualification": null,
        "capital": null,
        "address": null,
        "city": null,
        "station": null,
        "country": null,
        "phone": null,
        "fax": null,
        "photo": null,
        "web_site": null,
        "post": null,
        "industry": null,
        "orient": null,
        "registry_date": null,
        "note": null,
        "state": "0",
        "org_type": null,
        "type": null,
        "idx": "BAAA",
        "node": null,
        "parent_company_name": null,
        "children": [{
          "company_id": "3",
          "parent_company_id": "1",
          "name": "执法监察支队",
          "simple_name": null,
          "code": null,
          "owner": null,
          "qualification": null,
          "capital": null,
          "address": null,
          "city": null,
          "station": null,
          "country": null,
          "phone": null,
          "fax": null,
          "photo": null,
          "web_site": null,
          "post": null,
          "industry": null,
          "orient": null,
          "registry_date": null,
          "note": null,
          "state": "0",
          "org_type": null,
          "type": null,
          "idx": "BAAA",
          "node": null,
          "parent_company_name": null,
          "children": null
        }, {
          "company_id": "4",
          "parent_company_id": "1",
          "name": "土地储备中心",
          "simple_name": null,
          "code": null,
          "owner": null,
          "qualification": null,
          "capital": null,
          "address": null,
          "city": null,
          "station": null,
          "country": null,
          "phone": null,
          "fax": null,
          "photo": null,
          "web_site": null,
          "post": null,
          "industry": null,
          "orient": null,
          "registry_date": null,
          "note": null,
          "state": "0",
          "org_type": null,
          "type": null,
          "idx": "BBAA",
          "node": null,
          "parent_company_name": null,
          "children": null
        }],
    }
  },
  components: {
    formcheckselect
  },
  methods: {
    getValue() {
      console.info(this.$refs.checkSelect.$data.inputValue)
    },
    getLable() {
      console.info(this.$refs.checkSelect.$data.inputData)
    }
  }
}

function changeStatus() {
  alert("xxx");
}
</script>
<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #2c3e50;
  height: 100%;
}

.inputHeight .el-input__inner {
  height: 18px;
}
</style>

 

posted @ 2021-02-04 10:51  故木  阅读(1231)  评论(0编辑  收藏  举报