<el-row>
<!-- value默认回显 -->
<el-col>选中值返回{{ value }}</el-col>
<!-- 选中触发回显 -->
<el-col>选中的Key: {{selectData1.key}}</el-col>
<el-col>选中的label: {{selectData1.label}}</el-col>
<el-col>选中的子项对象: {{selectData1.checkedItems}}</el-col>
</el-row>
<all-select v-model="value" :list="list" :options="{title: 'name', label:'value', key: 'id'}" @returnData="returnData1" ></all-select>
<script>
import allSelect from './allSelect.vue'
export default {
components: {allSelect},
data() {
return {
selectData1: {},
list: [
{id: 1, name: '灭火器类型1' ,data: [{value: 'A',id: 1},{value: 'B',id: 2},{value: 'C',id: 3}]},
{id: 2, name: '灭火器类型2' ,data: [{value: 'D',id: 4},{value: 'E',id: 5},{value: 'F',id: 6}]}
],
value: '1,2,3,4',//[1,2] 或 1,2
}
},
methods: {
returnData1(value) {
this.selectData1 = value
},
}
}
注意:list中绑定的key值名 可以替换
如可以把 list中 data中 对象的 label 名 改成 label;key 改成key1; 需要在options对象中加入对应的字段 如:options=“{lable: ‘label’,key: ‘key1’}”
<all-select :options="{title: 'name',label: 'aaa', key: 'bbb'}" :list="[{id: 1, name: '灭火器类型1' ,data: [{aaa: '1',bbb: 1},{aaa: '2',bbb: 2},{aaa: '3',bbb: 3}]},{id: 2, name: '灭火器类型2' ,data: [{aaa: '1',bbb: 1},{aaa: '2',bbb: 2},{aaa: '3',bbb: 3}]}]"></all-select>
<!-- 全选-半选 多选组件分装 -->
<template>
<div>
<template v-if="formateList.length">
<div v-for="(item,index) in formateList" :key="index">
<el-checkbox :indeterminate="item.isIndeterminate" v-model="item.checkAll" @change="handleCheckAllChange($event, item,index)">{{item[allOption.title]}}</el-checkbox>
<div style="margin: 15px 0;"></div>
<el-checkbox-group v-model="item.key" @change="handleCheckedCitiesChange($event, item , index)">
<el-checkbox v-for="(it,idx) in item[allOption.dataKey]" :label="it[allOption.key]" :key="it[allOption.key]" @change="handleCheckedItem($event, item ,it, idx)">{{it[allOption.label]}}</el-checkbox>
</el-checkbox-group>
</div>
</template>
<template v-else>
<el-empty description="暂无数据"></el-empty>
</template>
<!-- {{`全选:`+ item.checkAll}}-{{`选中的子项:` + item.checkedItems}}-{{`数据:` + list}}--item.isIndeterminate--{{`半选` + item.isIndeterminate}} -->
</div>
</template>
<script>
/**
* list: [{id: 1, name: '灭火器类型1' ,data: [{value: '11',id: 1},{value: '12',id: 2},{value: '13',id: 3}]}], 渲染的数据格式
* options : {
* title //全选的名称
* dataKey //子项数组名
* label //子项的字典 值
* key //子项的字典 名
* realTime: ''//是否实时回显// true是 ; false 否
* }
*/
export default {
props: {
value: { type: Array | String, default: '' },
list: { type: Array, reqiured: true, default() { return [] } },
options: { type: Object, default() { return { title: 'title', dataKey: 'data', label: 'label', key: 'key', realTime: true } } }
},
data() {
return {
currentValue: [],//当前值
valueType: '', //值得类型
formateList: [],//初始化的数据
};
},
computed: {
allOption() {
let obj = { ...JSON.parse(JSON.stringify(this.options)) }
obj.title = this.options.title || 'title'//全选标题
obj.dataKey = this.options.dataKey || 'data'//子项数值
obj.label = this.options.label || 'label'//绑定的label
obj.key = this.options.key || 'key'//绑定的key
obj.realTime = this.options.realTime || true //判断是否实时监听,点一下就回显
return obj
},
},
watch: {//监听
value: {
handler(val) {
if (!val) return
if (!Array.isArray(val)) { this.currentValue = val.split(','); this.valueType = 'string' }
else { this.currentValue = val; this.valueType = 'array' }
},
deep: true,
immediate: true
},
currentValue: {
handler(val) {
if (!val) return
this.$nextTick(() => { this.initFormateList() })
},
deep: true,
immediate: true
},
list: {
handler(val) {
// console.log('监听List', val)
let arr = JSON.parse(JSON.stringify(val))
arr.forEach((item, index) => {
// this.$set(item, 'checkAll', false)
item.checkAll = false
item.isIndeterminate = false
item.checkedItems = []//子项选中的数据
item.label = []//子项选中的label
item.key = []//子项选中的key
})
this.formateList = arr
},
deep: true,
immediate: true
},
},
methods: {
//初始化
initFormateList() {
let arr = this.currentValue
this.formateList.forEach(item => {
item.checkedItems = []
item.label = []
item.key = []
item[this.allOption.dataKey].forEach(it => {
if (arr.includes(it[this.allOption.key] + '')) {
item.checkedItems.push(it)
item.label.push(it[this.allOption.label])
item.key.push(it[this.allOption.key])
}
})
if (item.checkedItems.length && item.checkedItems.length < item[this.allOption.dataKey].length) {
item.isIndeterminate = true
item.checkAll = false
} else if (item.checkedItems.length == item[this.allOption.dataKey].length) {//子项-全选
item.checkAll = true
item.isIndeterminate = false
}
})
if (!this.allOption.realTime) return;
this.$nextTick(() => this.resultData())
},
//点击全选
handleCheckAllChange(val, item, index) {//控制 key label checkedItems 的空 或 全选;还有半选
// console.log('全选事件', val, item, index)
item.checkedItems = val ? JSON.parse(JSON.stringify(item[this.allOption.dataKey])) : [];
item.isIndeterminate = false;
if (val) {//全选
item[this.allOption.dataKey].forEach(it => {
item.label.push(it[this.allOption.label])
item.key.push(it[this.allOption.key])
})
} else {//都不选
item.label = []
item.key = []
}
if (!this.allOption.realTime) return;
this.$nextTick(() => this.resultData())
},
//点击子项 group 事件
handleCheckedCitiesChange(value, item, index) {//控制全选 和半选 value:选中的key[],
// console.log('group事件', value, item, index,)
item.checkAll = value.length === item[this.allOption.dataKey].length;
item.isIndeterminate = value.length > 0 && value.length < item[this.allOption.dataKey].length
if (!this.allOption.realTime) return;
this.$nextTick(() => this.resultData())
},
//点击子项 item 事件
handleCheckedItem(val, item, it, index) {//控制 label数组 和 子项数组
// console.log('子项事件', val, item, it, index)
item.label = []
item.checkedItems = []
item[this.allOption.dataKey].forEach(itm => {
if (item.key.includes(itm[this.allOption.key])) {
item.label.push(itm[this.allOption.label])
item.checkedItems.push(itm)
}
})
},
//处理成功返回的数据
resultData() {
let returnObj = { key: [], label: [], checkedItems: [] }//返回的对象
let arr = JSON.parse(JSON.stringify(this.formateList))
let value = []
arr.forEach(item => {
value.push(...item.key)
returnObj.key.push(...item.key)
returnObj.label.push(...item.label)
returnObj.checkedItems.push(...item.checkedItems)
})
this.$emit('input', this.valueType == 'string' ? value.join(',') : value)
console.log('returnData事件触发')
this.$emit('returnData', returnObj)
}
}
};
</script>