在Vue.js项目中,ElementUI是一个非常流行的UI组件库,它提供了丰富的组件来帮助我们快速构建用户界面。其中,el-table
组件是一个非常强大的表格组件,支持多种数据展示和操作功能。在实际开发中,我们经常需要对表格中的某些列进行合算(如求和、平均值等),并将结果显示在表格的底部或指定位置。本文将详细介绍如何在Vue项目中使用ElementUI对el-table
的指定列进行合算。
在开始之前,确保你已经安装了Vue.js和ElementUI,并且已经在项目中引入了ElementUI的样式和组件。
npm install vue
npm install element-ui
在main.js
中引入ElementUI:
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
首先,我们创建一个基本的表格结构,展示一些数据。假设我们有一个表格,展示了一些商品的信息,包括商品名称、价格和数量。
<template>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="name" label="商品名称"></el-table-column>
<el-table-column prop="price" label="价格"></el-table-column>
<el-table-column prop="quantity" label="数量"></el-table-column>
</el-table>
</template>
<script>
export default {
data() {
return {
tableData: [
{ name: '商品A', price: 100, quantity: 2 },
{ name: '商品B', price: 200, quantity: 3 },
{ name: '商品C', price: 300, quantity: 1 },
],
};
},
};
</script>
接下来,我们需要对表格中的price
列和quantity
列进行合算,并显示在表格的底部。ElementUI的el-table
组件提供了一个summary-method
属性,可以用于自定义表格底部的合计行。
summary-method
属性我们可以在el-table
组件中使用summary-method
属性,并定义一个方法来计算指定列的总和。
<template>
<el-table :data="tableData" style="width: 100%" :summary-method="getSummaries">
<el-table-column prop="name" label="商品名称"></el-table-column>
<el-table-column prop="price" label="价格"></el-table-column>
<el-table-column prop="quantity" label="数量"></el-table-column>
</el-table>
</template>
<script>
export default {
data() {
return {
tableData: [
{ name: '商品A', price: 100, quantity: 2 },
{ name: '商品B', price: 200, quantity: 3 },
{ name: '商品C', price: 300, quantity: 1 },
],
};
},
methods: {
getSummaries(param) {
const { columns, data } = param;
const sums = [];
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = '合计';
return;
}
const values = data.map(item => Number(item[column.property]));
if (!values.every(value => isNaN(value))) {
sums[index] = values.reduce((prev, curr) => {
const value = Number(curr);
if (!isNaN(value)) {
return prev + curr;
} else {
return prev;
}
}, 0);
} else {
sums[index] = 'N/A';
}
});
return sums;
},
},
};
</script>
getSummaries
方法param
参数包含了表格的列信息columns
和数据data
。sums
数组用于存储每一列的合计值。运行上述代码后,表格底部会显示一个合计行,其中price
列和quantity
列分别显示了它们的总和。
默认情况下,ElementUI的合计行样式可能不符合我们的需求。我们可以通过自定义样式来美化合计行。
header-cell-class-name
和cell-class-name
我们可以使用header-cell-class-name
和cell-class-name
属性来为合计行的单元格添加自定义样式。
<template>
<el-table
:data="tableData"
style="width: 100%"
:summary-method="getSummaries"
:header-cell-class-name="headerCellClassName"
:cell-class-name="cellClassName"
>
<el-table-column prop="name" label="商品名称"></el-table-column>
<el-table-column prop="price" label="价格"></el-table-column>
<el-table-column prop="quantity" label="数量"></el-table-column>
</el-table>
</template>
<script>
export default {
data() {
return {
tableData: [
{ name: '商品A', price: 100, quantity: 2 },
{ name: '商品B', price: 200, quantity: 3 },
{ name: '商品C', price: 300, quantity: 1 },
],
};
},
methods: {
getSummaries(param) {
const { columns, data } = param;
const sums = [];
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = '合计';
return;
}
const values = data.map(item => Number(item[column.property]));
if (!values.every(value => isNaN(value))) {
sums[index] = values.reduce((prev, curr) => {
const value = Number(curr);
if (!isNaN(value)) {
return prev + curr;
} else {
return prev;
}
}, 0);
} else {
sums[index] = 'N/A';
}
});
return sums;
},
headerCellClassName({ row, column, rowIndex, columnIndex }) {
if (rowIndex === 0 && columnIndex === 0) {
return 'summary-header';
}
return '';
},
cellClassName({ row, column, rowIndex, columnIndex }) {
if (rowIndex === 0 && columnIndex === 0) {
return 'summary-cell';
}
return '';
},
},
};
</script>
<style>
.summary-header {
background-color: #f5f7fa;
font-weight: bold;
}
.summary-cell {
background-color: #f5f7fa;
font-weight: bold;
}
</style>
headerCellClassName
方法用于为表头单元格添加样式。cellClassName
方法用于为数据单元格添加样式。在实际应用中,表格的数据可能是动态变化的。我们需要确保在数据变化时,合计行能够实时更新。
我们可以使用Vue的watch
属性来监听表格数据的变化,并在数据变化时重新计算合计值。
<template>
<el-table
:data="tableData"
style="width: 100%"
:summary-method="getSummaries"
:header-cell-class-name="headerCellClassName"
:cell-class-name="cellClassName"
>
<el-table-column prop="name" label="商品名称"></el-table-column>
<el-table-column prop="price" label="价格"></el-table-column>
<el-table-column prop="quantity" label="数量"></el-table-column>
</el-table>
</template>
<script>
export default {
data() {
return {
tableData: [
{ name: '商品A', price: 100, quantity: 2 },
{ name: '商品B', price: 200, quantity: 3 },
{ name: '商品C', price: 300, quantity: 1 },
],
};
},
watch: {
tableData: {
handler() {
this.$nextTick(() => {
this.$refs.table.doLayout();
});
},
deep: true,
},
},
methods: {
getSummaries(param) {
const { columns, data } = param;
const sums = [];
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = '合计';
return;
}
const values = data.map(item => Number(item[column.property]));
if (!values.every(value => isNaN(value))) {
sums[index] = values.reduce((prev, curr) => {
const value = Number(curr);
if (!isNaN(value)) {
return prev + curr;
} else {
return prev;
}
}, 0);
} else {
sums[index] = 'N/A';
}
});
return sums;
},
headerCellClassName({ row, column, rowIndex, columnIndex }) {
if (rowIndex === 0 && columnIndex === 0) {
return 'summary-header';
}
return '';
},
cellClassName({ row, column, rowIndex, columnIndex }) {
if (rowIndex === 0 && columnIndex === 0) {
return 'summary-cell';
}
return '';
},
},
};
</script>
<style>
.summary-header {
background-color: #f5f7fa;
font-weight: bold;
}
.summary-cell {
background-color: #f5f7fa;
font-weight: bold;
}
</style>
watch
属性watch
属性用于监听tableData
的变化。tableData
发生变化时,调用this.$nextTick
确保DOM更新后重新布局表格。deep: true
表示深度监听,确保数组内部的变化也能触发监听。在某些情况下,表格可能包含多级表头。我们需要确保在计算合计值时,能够正确处理多级表头。
假设我们有一个多级表头的表格,展示商品的价格和数量,并且价格和数量分别有子列。
<template>
<el-table
:data="tableData"
style="width: 100%"
:summary-method="getSummaries"
:header-cell-class-name="headerCellClassName"
:cell-class-name="cellClassName"
>
<el-table-column prop="name" label="商品名称"></el-table-column>
<el-table-column label="价格">
<el-table-column prop="price" label="单价"></el-table-column>
<el-table-column prop="totalPrice" label="总价"></el-table-column>
</el-table-column>
<el-table-column label="数量">
<el-table-column prop="quantity" label="数量"></el-table-column>
<el-table-column prop="totalQuantity" label="总数量"></el-table-column>
</el-table-column>
</el-table>
</template>
<script>
export default {
data() {
return {
tableData: [
{ name: '商品A', price: 100, quantity: 2, totalPrice: 200, totalQuantity: 2 },
{ name: '商品B', price: 200, quantity: 3, totalPrice: 600, totalQuantity: 3 },
{ name: '商品C', price: 300, quantity: 1, totalPrice: 300, totalQuantity: 1 },
],
};
},
methods: {
getSummaries(param) {
const { columns, data } = param;
const sums = [];
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = '合计';
return;
}
const values = data.map(item => Number(item[column.property]));
if (!values.every(value => isNaN(value))) {
sums[index] = values.reduce((prev, curr) => {
const value = Number(curr);
if (!isNaN(value)) {
return prev + curr;
} else {
return prev;
}
}, 0);
} else {
sums[index] = 'N/A';
}
});
return sums;
},
headerCellClassName({ row, column, rowIndex, columnIndex }) {
if (rowIndex === 0 && columnIndex === 0) {
return 'summary-header';
}
return '';
},
cellClassName({ row, column, rowIndex, columnIndex }) {
if (rowIndex === 0 && columnIndex === 0) {
return 'summary-cell';
}
return '';
},
},
};
</script>
<style>
.summary-header {
background-color: #f5f7fa;
font-weight: bold;
}
.summary-cell {
background-color: #f5f7fa;
font-weight: bold;
}
</style>
el-table-column
中嵌套使用el-table-column
可以创建多级表头。getSummaries
方法中,我们仍然可以按照相同的方式计算每一列的总和。在某些情况下,表格中的数据可能不是简单的数字类型,而是包含复杂的数据结构。我们需要确保在计算合计值时,能够正确处理这些复杂数据类型。
假设我们有一个表格,展示商品的价格和数量,并且价格和数量分别包含货币单位和数量单位。
<template>
<el-table
:data="tableData"
style="width: 100%"
:summary-method="getSummaries"
:header-cell-class-name="headerCellClassName"
:cell-class-name="cellClassName"
>
<el-table-column prop="name" label="商品名称"></el-table-column>
<el-table-column prop="price" label="价格">
<template slot-scope="scope">
{{ scope.row.price.value }} {{ scope.row.price.unit }}
</template>
</el-table-column>
<el-table-column prop="quantity" label="数量">
<template slot-scope="scope">
{{ scope.row.quantity.value }} {{ scope.row.quantity.unit }}
</template>
</el-table-column>
</el-table>
</template>
<script>
export default {
data() {
return {
tableData: [
{ name: '商品A', price: { value: 100, unit: '元' }, quantity: { value: 2, unit: '件' } },
{ name: '商品B', price: { value: 200, unit: '元' }, quantity: { value: 3, unit: '件' } },
{ name: '商品C', price: { value: 300, unit: '元' }, quantity: { value: 1, unit: '件' } },
],
};
},
methods: {
getSummaries(param) {
const { columns, data } = param;
const sums = [];
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = '合计';
return;
}
const values = data.map(item => Number(item[column.property].value));
if (!values.every(value => isNaN(value))) {
sums[index] = values.reduce((prev, curr) => {
const value = Number(curr);
if (!isNaN(value)) {
return prev + curr;
} else {
return prev;
}
}, 0);
} else {
sums[index] = 'N/A';
}
});
return sums;
},
headerCellClassName({ row, column, rowIndex, columnIndex }) {
if (rowIndex === 0 && columnIndex === 0) {
return 'summary-header';
}
return '';
},
cellClassName({ row, column, rowIndex, columnIndex }) {
if (rowIndex === 0 && columnIndex === 0) {
return 'summary-cell';
}
return '';
},
},
};
</script>
<style>
.summary-header {
background-color: #f5f7fa;
font-weight: bold;
}
.summary-cell {
background-color: #f5f7fa;
font-weight: bold;
}
</style>
el-table-column
中使用slot-scope
可以自定义单元格的显示内容。getSummaries
方法中,我们提取复杂数据类型中的数值部分进行计算。在实际应用中,表格数据可能分页显示。我们需要确保在分页时,合计行能够正确显示当前页的数据总和。
假设我们有一个分页的表格,展示商品的价格和数量。
”`vue