二次封装的表格组件
<template>
<div class="com_table">
<el-table
ref="table"
v-loading="dataSource.loading"
border
style="width: 100%"
:data="dataSource.data"
@row-click="getRowData"
@selection-change="dataSource.handleSelectionChange"
>
<!-- 是否有多选 -->
<el-table-column
v-if="dataSource.isSelection"
type="selection"
:width="dataSource.selectionWidth || 50"
align="center"
/>
<!-- 是否需要序号 -->
<el-table-column
v-if="dataSource.isIndex"
type="index"
label="序号"
width="55"
align="center"
/>
<!-- 基本 -->
<el-table-column
v-for="(item, index) in dataSource.columns"
:key="index"
:align="item.align || 'right'"
:width="item.width"
:label="item.label"
:prop="item.prop"
>
<template scope="{row}">
<!-- 插槽列 -->
<div v-if="item.isSope"><slot :row="row"></slot></div>
<!-- 普通列 -->
<div v-else-if="!item.isCodeTableFormatter">
{{ row[item.prop] == 0 || row[item.prop] ? row[item.prop] : "--" }}
</div>
<!-- 对数据处理 -->
<div v-else>
{{ item.isCodeTableFormatter(row) }}
</div>
</template>
</el-table-column>
<!-- 操作 -->
<el-table-column
align="center"
:label="dataSource.operation.label"
:width="dataSource.operation.width"
v-if="dataSource.operation"
>
<!-- <template scope="{row}"> -->
<div class="opr_tb">
<div v-for="(item, index) in dataSource.operation.data" :key="index">
<el-button
:type="item.type"
:icon="item.icon"
size="small "
@click="item.handleRow"
>{{ item.label }}</el-button
>
</div>
</div>
<!-- </template> -->
</el-table-column>
</el-table>
<!-- 分页 -->
<div class="page">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="page.pageNum"
:page-sizes="[10, 20, 30, 40]"
:page-size="page.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="page.totalCount"
>
</el-pagination>
</div>
</div>
</template>
<script>
export default {
components: {},
props: {
dataSource: {
type: Object,
default() {
let _this = this;
return {
loading: false,
data: [
{
appIssueTime: new Date().getDate(),
appName: "测试",
appVersion: "1.0",
appPlatform: "Windows",
appAutoUpdate: "是",
},
],
columns: [
{
label: "时间",
prop: "appIssueTime",
isCodeTableFormatter: function (val) {
return timeFormat(val.appIssueTime);
},
},
{
label: "举例",
prop: "appName",
},
{
label: "APP版本",
prop: "appVersion",
},
{
label: "平台",
prop: "appPlatform",
isCodeTableFormatter: function (val) {
if (val.appPlatform === 1) {
return "IOS";
} else {
return "Android";
}
},
},
{
label: "是否自动更新",
prop: "appAutoUpdate",
isCodeTableFormatter: function (val) {
if (val.appAutoUpdate === 1) {
return "是";
} else {
return "否";
}
},
},
{
label: "更新描述",
prop: "appDesc",
width: 300,
},
{
label: "下载地址",
prop: "downloadAddr",
},
{
label: "发布人",
prop: "userName",
},
],
isSelection: false,
selectionWidth: 50,
isIndex: false,
handleSelectionChange: function (row, index) {
_this.$message({
message: `你选择了第(${index}+1)行,你还没有传入handleSelectionChange这是默认的,请传入处理函数!`,
type: "warning",
});
},
operation: {
// 表格有操作列时设置
label: "操作", // 列名
width: "200", // 根据实际情况给宽度
data: [
{
label: "修改", // 操作名称
type: "primary",
icon: "el-icon-edit",
// permission: "2010702", // 后期这个操作的权限,用来控制权限
handleRow() {
_this.$message({
message: `你还没有传入handleRow这是默认的,请传入处理函数!`,
type: "warning",
});
},
},
{
label: "删除", // 操作名称
type: "danger",
icon: "el-icon-delete",
// permission: "2010702", // 后期这个操作的权限,用来控制权限
handleRow() {
_this.$message({
message: `你还没有传入handleRow函数,请传入处理函数!`,
type: "warning",
});
},
},
],
},
};
},
},
},
data() {
return {
page: {
pageSize: 10,
totalCount: 0,
pageNum: 1,
},
};
},
//监听属性 类似于data概念
computed: {},
//监控data中的数据变化
watch: {},
//方法集合
methods: {
// 分页操作
handleSizeChange(pageSize) {
this.page.pageSize = pageSize;
this.$emit("getData", this.page, this);
},
handleCurrentChange(pageNum) {
this.page.pageNum = pageNum;
this.$emit("getData", this.page, this);
},
},
//生命周期 - 创建完成(可以访问当前this实例)
created() {},
//生命周期 - 挂载完成(可以访问DOM元素)
mounted() {
// this.dataSource.loading = false;
this.$emit("getData", this.page, this);
},
};
</script>
<style lang="css" scoped>
.com_table {
background-color: #ffffff;
}
.opr_tb {
display: flex;
justify-content: space-around;
}
.page {
display: flex;
justify-content: center;
}
</style>
使用的组件
<template>
<div class="xiao">
<CommonTable :dataSource="dataSources" @getData="getData">
<template v-slot="{ row: { merchantDtos } }">
<ul class="merchants">
<li v-for="(item, index) in merchantDtos" :key="index">
<span>{{ item.mchName }}</span>
</li>
</ul></template
>
</CommonTable>
</div>
</template>
<script>
import CommonTable from "@/components/CommonTable.vue";
export default {
components: {
CommonTable,
},
data() {
return {
_this: null,
dataSources: {
loading: false,
isSelection: true,
isIndex: true,
handleSelectionChange: (row) => {
console.log("row: ", row);
this.$message({
message: `你选择了${row},你还没有传入handleSelectionChange这是默认的,请传入处理函数!`,
type: "warning",
});
},
columns: [
{
label: "缴费标题",
prop: "title",
// isCodeTableFormatter: function (val) {
// },
},
{
label: "收费商户",
prop: "merchantDtos",
isSope: true,
},
{
label: "已缴费人次",
prop: "paidUserNum",
},
{
label: "发布时间",
prop: "createTime",
// isCodeTableFormatter: function (val) {
// },
},
{
label: "截止时间",
prop: "endTime",
// isCodeTableFormatter: function (val) {
// },
},
{
label: "发布人",
prop: "operator",
},
],
},
};
},
//监听属性 类似于data概念
computed: {},
//监控data中的数据变化
watch: {},
//方法集合
methods: {
getData(page, _this) {
this._this = _this;
console.log(_this.page);
this.dataSources.loading = true;
let params = { schoolId: this.$store.state.user.school.schoolId };
Object.assign(params, page);
delete params.totalCount;
this.postByCode("I_CPCS_AGENCY_BUSINESS_LIST", params).then((json) => {
this.dataSources.loading = false;
console.log(json);
this.dataSources.data = json.data.list;
let { pagenum, pagesize, totalcount } = json.data;
Object.assign(_this.page, {
pageNum: pagenum,
pageSize: pagesize,
totalCount: totalcount,
});
});
},
},
//生命周期 - 创建完成(可以访问当前this实例)
created() {},
//生命周期 - 挂载完成(可以访问DOM元素)
mounted() {},
};
</script>
<style lang="scss" scoped>
.xiao {
background-color: #ffffff;
padding: 20px;
}
</style>
总结
通过二次封装 Element UI 表格,我们可以减少代码重复和提高代码可读性。在二次封装过程中,需要对需求进行分析,确定二次封装的目标和实现方式;在封装组件时,可以使用 CSS 样式覆盖和函数式组件的方式,以简化表格定义和渲染;最后,在组件调用时,需要传入数据和表格列的配置,并调用自定义组件。