ag-grid-vue纵向合并单元格

本文介绍了如何在ag-grid-vue中实现纵向合并单元格,包括基本使用、动态控制显示内容、行样式、合并单元格加选择框、分页等功能。详细讲解了配置项、数据处理和CSS样式,提供了示例代码和踩坑经验。
摘要由CSDN通过智能技术生成

一、安装ag-grid-vue并引入样式

ag-grid中文文档
ag-grid英文文档

1. 安装ag-grid包

npm install ag-grid-community ag-grid-vue --save-dev

2. 引入样式文件(App.vue),这里以ag-theme-alpine主题为例

  @import '../node_modules/ag-grid-community/styles/ag-grid.css';
  @import '../node_modules/ag-grid-community/styles/ag-theme-alpine.css';
  @import "style/ag-grid.scss";

二、使用案例

1. 基本使用

(1) 引入AgGridVue

import {
        AgGridVue
    } from "ag-grid-vue3";

(2) html部分

<ag-grid-vue class="ag-theme-alpine ag-wrap" :columnDefs="orderDefs" :rowData="orderData"
                @gridReady="onGridReady">
</ag-grid-vue>

(3) js部分

data

    const orderDefs = [{
            headerName: '订单编号',
            field: 'orderCode',
            width: 200,
        }, {
            headerName: '类型',
            field: 'sendType',
        }, {
            headerName: '日期',
            field: 'sendDate',
        }, {
            headerName: '状态',
            field: 'orderStatus',
        }
    ]
    const orderData = [
           {
                id: 1,
                orderCode: "YHHB2022082001001",
                sendType: "正常检测",
                sendDate: "2022-08-20",
                orderStatus: "待发送",
            },
            {
                id: 2,
                orderCode: "YHHB2022082001002",
                sendType: "申请复检",
                sendDate: "2022-08-20",
                orderStatus: "待发送",
            },
            {
                id: 3,
                orderCode: "YHHB2022082001003",
                sendType: "正常检测",
                sendDate: "2022-08-20",
                orderStatus: "待发送",
            }
    ]

(4) css部分

   .app-container {
        height: 100%;
        padding: 12px;
    }

    .form-wrap {
        height: 50%;
        display: flex;
        flex-direction: column;
        border: 1px solid #babfc7;
        padding: 6px;
        margin-bottom: 10px;
    }

    .ag-wrap {
        flex: 1;
    }
    
   :deep(.ag-ltr .ag-cell) {
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 0;
        text-align: center;
    }
    
    :deep(.ag-header-cell-label) {
        justify-content: center;
    }     

(5) 展示效果

在这里插入图片描述

2. 根据数值动态控制显示内容或者改变样式

(1) 配置orderDefs里面某个字段的cellRenderer配置项

{
            headerName: '检测结果',
            field: 'projectCheckValue',
            cellRenderer: (params) => {
                if (params.value === '合格') {
                    return `<div style="background:#CAF982;width:100%" }}> ${params.value}</div>`;
                } else if (params.value === '不合格') {
                    return `<div style="background:#EC808D;width:100%" }}> ${params.value}</div>`;
                } else {
                    return `<div style="background:#D7D7D7;width:100%" }}> ${params.value}</div>`;
                }
            }
        }

(2) 展示效果

在这里插入图片描述

3. 动态控制行的样式

这里以判断订单状态来改变行的背景色为例

(1) 配置grid-options

html

<ag-grid-vue class="ag-theme-alpine ag-wrap" :columnDefs="orderDefs" :rowData="orderData"
                :grid-options="gridOptions" @gridReady="onGridReady">
</ag-grid-vue>
data
 const gridOptions = {
        rowHeight: 40,
        headerHeight: 40, // 设置表格表头的行高
        getRowStyle: (params) => {
            return ChangRowColor(params)
        }
    };
methods
// 渲染行的颜色
    const ChangRowColor = (params) => {
        if (params.data.orderStatus=== '待发送') {
            return {
                'background-color': '#81D3F8'
            }
        }
    };
  // 表格创建完成后执行
  const onGridReady = (params) => {
    // 获取gridApi
    gridApi.value = params.api;
    columnApi.value = params.columnApi;
    // 调整表格列宽大小自适应
    gridApi.value.sizeColumnsToFit();
  }

(2) 展示效果

在这里插入图片描述

4. 纵向合并单元格+选择框

效果如图:
在这里插入图片描述

(1) 开启suppressRowTransform等属性,注意拼写!!本人踩了个大坑

<ag-grid-vue class="ag-theme-alpine ag-wrap" :columnDefs="columnDefs" :rowData="rowData"
      :suppressRowTransform="true" :rowSelection="rowSelection" @gridReady="onGridReady"
      @selection-changed="onSelectionChanged">
</ag-grid-vue>

(2) data数据+方法+css

data
const rowSelection = 'multiple'; // 设置多选
配置columnDefs
const columnDefs = [
{
      headerName: '',
      // checkboxSelection: true,
      headerCheckboxSelection: true,
      width: 100,
      cellClassRules: {
        'span-item': "value !== ''"
      },
      rowSpan: (params) => {
        return rowSpanItem(params)
      },
      checkboxSelection: (params) => {
        return params.data ?
          params.node.childIndex % 5 === 0 :
          false;
      },
      checkboxSelection: true,//禁止拖动
    },
    {
      headerName: '序号',
      maxWidth: 120,
      rowSpan: (params) => {
        return rowSpanItem(params)
      },
      cellClassRules: {
        'span-item': "value !== ''"
      },
      cellRenderer: (params) => {
        if (params.node && params.node.childIndex % 5 === 0) {
          return `<div style="height:100%;" }}> ${params.node.childIndex/5+1}</div>`;
        }
      }
    }, {
      headerName: '样品编码',
      field: 'sampleCode',
      width: 200,
      rowSpan: (params) => {
        return 5;
      },
      cellClassRules: {
        'span-item': function (params) {
          if (params.data.id !== '') {
            return true
          } else {
            return false;
          }
        }
      },
      cellRenderer: (params) => {
        if (params.data.id !== '') {
          return `<div }}> ${params.value}</div>`; // 用于字体垂直居中   
        }
      }
    },
]
methods
  // 复选框发生改变时 判断全选框是否勾选
  const onSelectionChanged = (val) => {
    var selRows = gridApi.value.getSelectedRows();
    let arr = rowData.value.filter(item => {
      return item.sampleCode !== ""
    })
    if (arr.length === selRows.length) {
      gridApi.value.selectAll();
    }
  };
    // 合并方法
  const rowSpanItem = (param) => {
    if (param.node && param.node.childIndex % 5 === 0) {
        // console.log(param.node.childIndex)
        return 5
      } else {
        return 1
    }
  };
css样式
  :deep(.span-item) {
    background-color: #fff;
    border-right: 1px solid lightgrey;
    border-bottom: 1px solid lightgrey;
  }
  :deep(.ag-cell-value) {
    border-right: 1px solid lightgrey;
  }

  :deep(.ag-cell-wrapper .ag-cell-value) {
    border: 0;
  }

  :deep(.ag-cell-value span) {
    width: 100%;
  }

  :deep(.ag-center-cols-container) {
    overflow: hidden;
  }

  :deep(.ag-ltr .ag-cell-focus:not(.ag-cell-range-selected):focus-within) {
    border-color: transparent;
    border-right: 1px solid lightgrey;
    border-bottom: 1px solid lightgrey;
  }

(3) 重点!!数据格式

以这里5行一组为例,只有每组的第一条需要id,其他的id置为空即可
在这里插入图片描述

5. 纵向合并后添加分页

(1)使用ant-design自定义分页

    <a-pagination v-model:current="current" v-model:pageSize="pageSize" :total="total" show-size-changer :show-total="total => `共 ${total} 条`" 
    @showSizeChange="onShowSizeChange" />

(2)获取列表后计算total值

total.value = rowData.value.length / 5

(3)methods方法

  // 分页发生改变
  const onShowSizeChange = (page: number, size: number) => {
    pageSize.value = size * 5;
    current.value = page;
    // 调用接口
  }

6. 补充一种动态合并纵向单元格方法

rowSpan配置

判断多个属性

// 合并方法
  const rowSpanItem = (param) => {
    // 定义需要合并的属性名
    const arr = ["sampleCode", "sampleType"];
    // console.log(param.data)
    if (arr.indexOf(param.column.colId) !== -1) {
      const data = arr.slice(0, arr.indexOf(param.column.colId) + 1);
      // 每个值第一次出现时对应的索引
      const first = rowData.value.findIndex(item => data.every((v) => item[v] === param.data[v]));
      // console.log(first)
      if (param.node.childIndex === first) {
        // 计算与索引值相同值出现的次数
        const rowspan = rowData.value.filter(item => {
          return data.every(v => item[v] === param.data[v]);
        }).length;
        return rowspan;//返回合并行
      } else {
        return 1;
      }
    } 
  }

判断单个属性

const first = rowData.value.findIndex(item => item['sample_code'] === params.data['sample_code']);
                if (params.node.childIndex === first) {
                    const rowspan = rowData.value.filter(item => {
                        return item['sample_code']===params.data['sample_code']
                    }).length;
                    return `<div style="height:100%;" }}> ${params.node.childIndex/rowspan+1}</div>`;
                }

7. 配置默认项

<ag-grid-vue
        class="ag-theme-alpine ag-wrap"
        :columnDefs="orderDefs"
        overlayNoRowsTemplate="暂无数据"
        :rowData="orderData"
        :defaultColDef="defaultColDef"
        :headerHeight="28"
        :rowHeight="28"
        rowSelection="multiple"
        :grid-options="gridOptions"
        @gridReady="onGridReady"
        @rowClicked="onRowClicked"
      >
      </ag-grid-vue>
const defaultColDef = {
  width: 170,
  resizable: true,
  cellStyle: { "border-right-color": "#e8eaed" },
};

8. 单元格内操作栏添加点击事件(2个以上)

配置columnDefs

{
    headerName: "操作",
    field: "action",
    width: 400,
    rowSpan: (params) => {
      return rowSpanItem(params);
    },
    cellClassRules: {
      "span-item": "value !== ''",
    },
    cellRenderer: (params) => {
      var btn1 = document.createElement("span");
      console.log(params);
      btn1.innerHTML = "检测结果归档";
      btn1.style = "margin-right:6px;color:#4C78FC";
      btn1.addEventListener("click", () => {
        setTimeout(() => {
          let arr = [];
          arr[0] = active.value;
          const req = {
            sample_ids: arr,
          };
          const res = approveResult(req);
          if (res.code === "000000") {
          }
        }, 500);
      });
      var btn2 = document.createElement("span");
      btn2.innerHTML = "重新录入数据";
      btn2.style = "color:#4C78FC";
      btn2.addEventListener("click", () => {
        setTimeout(() => {
          let arr = [];
          arr[0] = active.value;
          const req = {
            sample_ids: arr,
          };
          const res = reRecord(req);
          if (res.code === "000000") {
          }
        }, 500);
      });
      const cell = document.createElement("div");
      cell.style = "display:flex;";
      cell.appendChild(btn1);
      cell.appendChild(btn2);
      return cell;
    },
    lockPosition: true,
  },
const rowSpanItem = (params) => {
  const first = rowData.value.findIndex(
    (item) => item["sample_code"] === params.data["sample_code"]
  );
  if (params.node.childIndex === first) {
    const rowspan = rowData.value.filter((item) => {
      return item["sample_code"] === params.data["sample_code"];
    }).length;
    return rowspan;
  } else {
    return 1;
  }
};

9. 开启suppressRowClickSelection属性

合并单元格中编辑子数据时会触发行事件,导致gridApi.value.getSelectedRows方法中出现值,开始suppressRowClickSelection属性后就可以避免这一现象发生

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

trabecula_hj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值