Bootstrap

vxe-grid实现嵌套table,自实现联动多选

文章目录

效果图

在这里插入图片描述

1721384084734


地址:https://live.csdn.net/v/410888?spm=1001.2014.3001.5501

<vxe-grid ref='gridWarehouse' v-bind="gridWarehouseOptions" v-if="tableHeight" :height="tableHeight"
		  :expand-config="{iconOpen: 'vxe-icon-square-minus', iconClose: 'vxe-icon-square-plus'}"
		  @checkbox-change="gridWarehouseCheckboxChangeEvent" @checkbox-all="gridWarehouseCheckboxAllEvent"
		  @toggle-row-expand="toggleExpandChangeEvent">
  //官方写法展开行插槽
  <template #deliverDetailList="{ row ,rowIndex }">
  	//嵌套的table setCheckboxRow无效一定要加上checkbox-config配置:checkField: 'checked'
  	//checkbox-change:接收回调参数 param 并传递自定义参数 deliverOrderCode
	<vxe-table :ref="'tableWarehouse'+ row.deliverOrderCode" border stripe :data="row.recRetDetailVoList"
			   align="center" style="margin-left: 40px" min-height="80" row-id="id"
			   :checkbox-config="{ labelField: '', checkField: 'checked', highlight: true, trigger: 'row', reserve: false , range: true}"
			   @checkbox-change="(param) => tableWarehouseCheckboxChangeEvent(param,row.deliverOrderCode)"
			   @checkbox-all="(checked) => tableWarehouseCheckboxAllEvent(checked,row.deliverOrderCode)">
	  <vxe-column type="checkbox" width="40"/>
	  <vxe-column type="seq" title="#" width="50"/>
	  <vxe-column field="voucherNum" title="单据号"/>
	  <vxe-column field="voucherQuantity" title="数量"/>
	  <vxe-column field="materialCode" title="物料编码"/>
	  <vxe-column field="materialName" title="物料"/>
	  <vxe-column field="unitName" title="单位"/>
	  <vxe-column field="spec" title="规格"/>
	  <vxe-column field="model" title="型号"/>
	</vxe-table>
  </template>
</vxe-grid>
//外层grid table的勾选事件
gridWarehouseCheckboxChangeEvent({checked, row}) {
  //动态获取里层的table的refs,如果是undefined说明用户没有手动展开
  const $tableWarehouse = this.$refs[`tableWarehouse${row.deliverOrderCode}`]
  if ($tableWarehouse === undefined) {
    this.updateBillData(checked, row.recRetDetailVoList)
  } else {
    $tableWarehouse.toggleAllCheckboxRow()
  }
},
//外层grid table的全选事件
gridWarehouseCheckboxAllEvent({checked, $event}) {
  const $gridWarehouse = this.$refs.gridWarehouse
  const gridWarehouseTableData = $gridWarehouse.getTableData().tableData
  for (let i of gridWarehouseTableData) {
    const $tableWarehouse = this.$refs[`tableWarehouse${i.deliverOrderCode}`]
    if ($tableWarehouse === undefined) {
      this.updateBillData(checked, i.recRetDetailVoList)
    } else {
     //toggleAllCheckboxRow 用于 type=checkbox,切换所有行的选中状态
      $tableWarehouse.toggleAllCheckboxRow()
    }
  }
},
//里层grid table的勾选事件
tableWarehouseCheckboxChangeEvent(param, deliverOrderCode) {
  const $tableWarehouse = this.$refs[`tableWarehouse${deliverOrderCode}`]
  //setCheckboxRow 用于 type=checkbox 复选框,设置行为选中状态,第二个参数为选中与否
  $tableWarehouse.setCheckboxRow(param.row, param.checked)
  if (param.checked) {
	const index = this.billData.findIndex(item => item.id === param.row.id)
	if (index === -1) {
	  this.billData.push(param.row)
	}
  } else {
	for (let tt = 0; tt < this.billData.length; tt++) {
	  if (param.row.id === this.billData[tt].id) {
		this.billData.splice(tt, 1)
		break;
	  }
	}
  }
  const $gridWarehouse = this.$refs.gridWarehouse
  const rowId = this.getGridWarehouseTableDataRowId($gridWarehouse.getTableData().tableData, param.row.deliverOrderCode)
  if ($tableWarehouse.isAllCheckboxChecked()) {
    //getRowById 根据行的唯一主键获取行(需要 row-config.keyField)
	$gridWarehouse.setCheckboxRow($gridWarehouse.getRowById(rowId), true)
  } else {
    //getCheckboxRecords 用于 type=checkbox,获取当前已选中的行数据,包含当前列表(如果 isFull=true 包含完整列表)
	const selectRecordLength = $tableWarehouse.getCheckboxRecords().length
	if (selectRecordLength === 0) {
	  $gridWarehouse.setCheckboxRow($gridWarehouse.getRowById(rowId), false)
	} else if (selectRecordLength < $tableWarehouse.getTableData().tableData.length) {
	  $gridWarehouse.setCheckboxRow($gridWarehouse.getRowById(rowId), false)
	}
  }
},
//里层grid table的全选事件
tableWarehouseCheckboxAllEvent(param, deliverOrderCode) {
  const $gridWarehouse = this.$refs.gridWarehouse
  const $tableWarehouse = this.$refs[`tableWarehouse${deliverOrderCode}`]
  const tableWarehouseTableData = $tableWarehouse.getTableData().tableData
  const gridWarehouseTableData = $gridWarehouse.getTableData().tableData
  let rowId = ''
  for (let i of gridWarehouseTableData) {
	if (i.deliverOrderCode === tableWarehouseTableData[0].deliverOrderCode) {
	  rowId = i._X_ROW_KEY
	  break;
	}
  }
  $gridWarehouse.setCheckboxRow($gridWarehouse.getRowById(rowId), param.checked)
  for (let j of tableWarehouseTableData) {
	$tableWarehouse.setCheckboxRow($tableWarehouse.getRowById(j.id), param.checked)
  }
  this.updateBillData(param.checked, tableWarehouseTableData)
},
//根据deliverOrderCode获取$gridWarehouse的rowId,用于定位外层TableData,外层的rowId是默认的
getGridWarehouseTableDataRowId(gridWarehouseTableData, deliverOrderCode) {
      let rowId = ''
      for (let i of gridWarehouseTableData) {
        if (i.deliverOrderCode === deliverOrderCode) {
          rowId = i._X_ROW_KEY
          break;
        }
      }
      return rowId;
    },
//记录用户选取的数据
updateBillData(checked, recRetDetailVoList) {
  //checked勾选状态:true | false
  if (checked) {
	for (let t of recRetDetailVoList) {
	  const index = this.billData.findIndex(item => item.id === t.id)
	  if (index === -1) {
		this.billData.push(t)
	  }
	}
  } else {
	for (let t of recRetDetailVoList) {
	  for (let tt = 0; tt < this.billData.length; tt++) {
		if (t.id === this.billData[tt].id) {
		  this.billData.splice(tt, 1)
		  break;
		}
	  }
	}
  }
},
//table插槽展开事件,官方解释:当行展开或收起时会触发该事件
//我这主要是用户先勾选了外层的table行,那么用户在展开时,初始化勾选状态
toggleExpandChangeEvent({$rowIndex, column, columnIndex, $columnIndex, $event}) {
this.$nextTick(() => {
    for (let i of this.billData) {
      const $tableWarehouse = this.$refs[`tableWarehouse${i.deliverOrderCode}`]
      if ($tableWarehouse !== undefined) {
        const index = $tableWarehouse.getTableData().tableData.findIndex(item => item.id === i.id)
        if (index !== -1) {
          $tableWarehouse.setCheckboxRow($tableWarehouse.getRowById(i.id), true)
        }
      }
    }
  })
}

PS:
目前存在bug
1.用户展开了嵌套的table,再勾选外层table的行,全setCheckboxRow为true,但是嵌套的table表头的全选框不会有勾选样式。
2.用户不展开嵌套的table,勾选外层table的行,再展开嵌套的table,此时表头全选框会是勾选状态,但是用户再次点击外层table的行去取消勾选时,嵌套table表头的全选框还是勾选状态。

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;