ag-grid-vue使用经验:纵向合并,动态控制显示内容
一、安装ag-grid-vue并引入样式
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属性后就可以避免这一现象发生