element ui el-checkbox 全选 半选 组件分装

示例

element ui el-checkbox 全选 半选 组件分装_第1张图片

引用

<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>

你可能感兴趣的:(vue,element-ui,javascript,vue.js,elementui,el-checkbox,全选,半选)