- 概述
注入树形数据加载出下拉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>