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表头的全选框还是勾选状态。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 安装 vxe-table ``` npm install vxe-table --save ``` 2. 在 Vue 项目中引用 vxe-table ```javascript import Vue from 'vue' import 'xe-utils' import VXETable from 'vxe-table' import 'vxe-table/lib/style.css' Vue.use(VXETable) ``` 3. 在 Vue 模板中使用 vxe-table ```html <vxe-table :data="tableData" checkbox-config="{range: true}"> <vxe-table-column type="selection" width="60"></vxe-table-column> <vxe-table-column field="name" title="姓名"></vxe-table-column> <vxe-table-column field="age" title="年龄"></vxe-table-column> <vxe-table-column field="address" title="地址"></vxe-table-column> </vxe-table> ``` 4. 在 Vue 实例中定义数据 ```javascript export default { data() { return { tableData: [ { name: '张三', age: 20, address: '北京市' }, { name: '李四', age: 30, address: '上海市' }, { name: '王五', age: 40, address: '广州市' }, { name: '赵六', age: 50, address: '深圳市' } ] } } } ``` 5. 使用多选下拉框 ```html <template> <div> <vxe-dropdown ref="dropdown" v-model="value" :options="options" multiple> <template #option="{ option, $index }"> <vxe-checkbox :label="option.value" :content="option.label" :indeterminate="option.indeterminate" :checked="option.checked" @change="handleChange($event, option)"></vxe-checkbox> </template> </vxe-dropdown> <vxe-table :data="tableData" checkbox-config="{range: true}" ref="table"> <vxe-table-column type="selection" width="60"></vxe-table-column> <vxe-table-column field="name" title="姓名"></vxe-table-column> <vxe-table-column field="age" title="年龄"></vxe-table-column> <vxe-table-column field="address" title="地址"></vxe-table-column> </vxe-table> </div> </template> ``` ```javascript export default { data() { return { options: [ { label: '张三', value: '1' }, { label: '李四', value: '2' }, { label: '王五', value: '3' }, { label: '赵六', value: '4' }, ], value: ['1', '2'], tableData: [ { name: '张三', age: 20, address: '北京市' }, { name: '李四', age: 30, address: '上海市' }, { name: '王五', age: 40, address: '广州市' }, { name: '赵六', age: 50, address: '深圳市' } ] } }, methods: { handleChange (checked, option) { if (checked) { this.value.push(option.value) } else { const index = this.value.indexOf(option.value) if (index > -1) { this.value.splice(index, 1) } } } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值