在日常开发后端管理系统项目中,用于展示数据多会用表格进行展示,这样我们可以把相同的部分处理出来,二次封装一个基于elementUI中的el-table封装一个简单的表格组件,进行多页面的数据展示的复用。
首先第一步肯定要引入elementUI组件库,我们可以使用全局引入和局部引入两种的方式
elementUI具体使用方法可以参考elementUI官网:
Element - The world's most popular Vue UI framework
这边个人推荐使用局部引入,这样可以减少项目的体积
引入之后,接下来我们就可以进行表格的二次封装了:
子组件template部分:
<!-- 表格组件 -->
<template>
<el-table
:data="data"
style="width: 100%"
highlight-current-row
@selection-change="handleSelectionChange">
<el-table-column
v-if="showSelect"
type="selection"
width="55"
align="center">
<!-- //TODO showSelect:表格组件是否带多选框类型:带或不带 -->
</el-table-column>
<el-table-column
align="center"
v-for="item in columns"
:key="item.prop"
:prop="item.prop"
:label="item.label"
:width="item.width"
:formatter="item.formatter">
</el-table-column>
<el-table-column v-if="showStatus" label="状态" align="center">
<!-- // TODO showStatus:是否带状态开关 -->
<template slot-scope="scope">
<el-switch
v-model="scope.row.status"
active-value="0"
inactive-value="1"
@change="handleStatusChange(scope.row)">
</el-switch>
</template>
</el-table-column>
<el-table-column
v-if="showHandle"
fixed="right"
label="操作"
width="150"
align="center">
<!-- //TODO showHandle:是否带操作栏 -->
<template slot-scope="scope">
<slot :item="scope.row"></slot>
</template>
</el-table-column>
</el-table>
</template>
template部分的复选框、状态改变、操作栏使用v-if判断是否显示,父组件传入Boolean值选择是否需要,使用示例请看父组件template部分
一般表格会需要操作栏,那么我们使用插槽在子组件中对操作栏进行自定义,父组件中使用插槽添加自己想要的按钮,例子见代码中详情按钮
有时候会需要使用formatter解析表格中的部分参数(对时间进行处理、钱加$符号、后端返回状态对它进行展示),需要在子组件中定义formatter方法,让它使用父组件中传入的formatter函数即可,具体可看父组件data中的tableColumns
子组件script部分:
<script>
export default {
props: {
data: {
type: Array,
required: true,
},
columns: {
type: Array,
required: true,
},
showSelect: {
type: Boolean,
default: false,
},
showHandle: {
type: Boolean,
default: false,
},
showStatus: {
type: Boolean,
defalut: false,
},
},
methods: {
// 多选框
handleSelectionChange(val) {
this.multipleSelection = val;
this.$emit("selectionData", val);
},
// 状态开关
handleStatusChange(row) {
let text = row.status === "0" ? "启用" : "停用";
this.$confirm('确认要"' + text + '"吗?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
this.msgSuccess(text + "成功");
// console.log(row);
this.$emit("statusData", row);
})
.catch(function () {
row.status = row.status === "0" ? "1" : "0";
});
},
},
};
</script>
子组件在data中规定父组件传递给子组件数据的类型,默认值等
子组件添加一些基础方法,把值传递给父组件,例如点击多选框后,触发子组件中复选框方法,利用$emit子传父自定义方法名,把选中数据传递给父组件,父组件中调用 @selectionData="getData"
父组件template部分:
<template>
<div class="app-container">
<el-page-header content="详情页面"></el-page-header>
<Table
:data="tableData"
:columns="tableColumns"
showSelect
showHandle
showStatus
v-loading="loading"
@selectionData="getData">
<template slot-scope="{ item }">
<el-button @click="handleTableClick(item)" type="text" size="small">
详情
</el-button>
</template>
</Table>
</div>
</template>
父组件sccript部分:
<script>
import * as Apis from "@/api/comparison/result/index";
import Table from "@/components/DataTable/index"; // 引入组件
import { dateFormat } from "@/utils/index"; // 时间处理函数
export default {
components: { // 使用子组件
Table: Table,
},
data() {
return {
queryParams: {
id: null,
customerNo: "", // 客户编号
contrastResult: "", // 客户状态查询
outOrderNos: [], // 订单号
trackNumbers: [], // 运单号
},
// 加载中遮罩层
loading: false,
tableData: [],
tableColumns: [
{ prop: "customerNo", label: "客户编号", width: "150" },
{ prop: "outOrderNo", label: "客户订单号" },
{ prop: "trackNumber", label: "运单号" },
{
prop: "priceTotal",
label: "总计",
width: "100",
formatter: function (row, column, cellValue, index) {
if (row.priceTotal) {
return `$${row.priceTotal}`;
}
},
},
{ prop: "importTime", label: "时间", formatter: dateFormat },
{
prop: "contrastResult",
label: "状态",
formatter: function (row, column, cellValue, index) {
switch (row.contrastResult) {
case 0:
return "已打印";
case 1:
return "未打印";
case -1:
return "运输中";
case -2:
return "已取消";
default:
break;
}
},
},
],
],
};
},
methods: {
getData(val){
console.log(val,'子组件传递过来selection选中的数据');
},
async getList() {
this.loading = true;
const data = await Apis.contrastDetail(this.queryParams);
console.log(data);
this.loading = false;
this.total = data.total;
this.tableData = data.rows;
},
// 详情按钮
handleTableClick(row) {
console.log(row, "当前点击行中的数据");
},
},
created() {
this.getList()
},
};
</script>
在父组件data中tableColumns传入formatter方法,就可以对部分数据进行解析、处理。