前言
很多业务中有类似表格的操作,尤其是类似后台操作的业务产品等更需要将表格封装起来,以此减轻代码工作量提升开发效率,而且还能统一修改表格样式等等。
这里以ElementUI组件库为前提封装
如图所示:
项目中大量用到表格时候,这时我们就要考虑把表格进行封装,可以减少代码,提高复用性,维护性好。
原始代码
首先看一下没封装过的代码
<template>
<div>
<el-table :data="dataList" border style="width: 100%">
<el-table-column fixed prop="index" label="序号" width="113">
</el-table-column>
<el-table-column prop="matterStyleName" label="通道名称" width="120">
</el-table-column>
<el-table-column prop="province" label="标记类型" width="120">
</el-table-column>
<el-table-column prop="userName" label="操作用户" width="120">
</el-table-column>
<el-table-column prop="description" label="描述" width="300">
</el-table-column>
<el-table-column fixed="right" label="操作" width="100">
<template slot-scope="scope">
<el-button @click="dialogShow(scope.row)" type="text" size="small">查看录像</el-button>
</template>
</el-table>
</div>
</template>
<script>
import { matter, matterPage, matterExport } from "@api";
import { handleTime } from "@utils/date";
export default {
components: {
tableConfig: () => import("@com/jkTableConfig"),
videoQuertdialog: () =>
import("@views/Analysis/components/videoQuertdialog.vue"),
},
data() {
return {
matterTypes: [],
userId: 0,
pageSize: 20,
pageIndex: 1,
dataList: [],
row: 0,
};
},
created() {
this.getMatter();
this.getMatterPage();
},
methods: {
async getMatter() {
await matter().then((res) => {
if (res.status == 200) {
this.matterTypes = res.message;
} else {
this.$message({
message: `获取标记类型错误,http状态码:${res.status}`,
type: "warning",
});
}
});
},
async getMatterPage() {
await matterPage(
this.userId,
this.formInline.matterType === null ? 0 : this.formInline.matterType,
{
PageSize: this.pageSize,
PageIndex: this.pageIndex,
StartTime: this.formInline.startTime,
EndTime: this.formInline.endTime,
}
).then((res) => {
if (res.status == 200) {
this.row = res.message.count;
this.dataList = res.message.data;
} else {
this.$message({
message: `获取标记类型错误,http状态码:${res.status}`,
type: "warning",
});
}
});
},
dialogShow(row) {
this.$refs.videoQuertdialog.show(row);
},
},
};
</script>
复制代码
表格封装
tab_config.vue
<template>
<div class="table">
<el-table
class="elTable"
stripe
height="100%"
border
:header-cell-style="tableHeaderColor"
:cell-style="tableClass"
:data="tableData"
>
<template v-for="item in table_config.thead">
<el-table-column
v-if="item.type === 'function'"
:key="item.prop"
:label="item.label"
:width="item.width"
:prop="item.prop"
align="center"
>
<template slot-scope="scope">
<span v-html="item.callback && item.callback(scope.row)"></span>
</template>
</el-table-column>
<!-- 操作 -->
<el-table-column
v-else-if="item.type === 'operation'"
:key="item.prop"
:prop="item.prop"
:label="item.label"
:width="item.width"
>
<template slot-scope="scope">
<el-button
class="btn"
v-for="items in item.actionButtons"
:key="items.title"
:type="items.type"
@click="item.callback(scope.row, items.title)"
:icon="items.icon"
:circle="items.circle"
><span v-if="!items.circle">{{ items.title }}</span></el-button
>
</template>
</el-table-column>
<!-- 普通渲染 -->
<el-table-column
v-else
:key="item.prop"
:prop="item.prop"
:label="item.label"
:width="item.width"
:min-width="item.minWidth"
align="center"
></el-table-column>
</template>
</el-table>
</div>
</template>
<script>
export default {
name: "tableConfig",
props: {
// 表格数据
config: {
type: Object,
default: () => {},
},
tableData: {
type: Array,
default: () => {},
},
data() {
return {
table_config: {
thead: [],
},
};
},
methods: {
//初始化表格数据
initConfig() {
for (let key in this.config) {
if (Object.keys(this.table_config).includes(key)) {
this.table_config[key] = this.config[key];
}
}
},
// 斑马线样式
tableClass({ row, rowIndex }) {
if (rowIndex % 2 == 1) {
return "background-color:var(--bgColor1);borderColor:var(--deepBlue);color:#fff;padding:4px";
} else {
return "background-color:var(--bgColor2);borderColor:var(--deepBlue);color:#fff;padding:4px";
}
},
// 表头样式
tableHeaderColor({ row, column, rowIndex, columnIndex }) {
return "background-color:var(--bgColor3);color:#fff;font-wight:500;font-size:14px;text-align:center;borderColor:var(--deepBlue);padding:4px";
},
},
watch: {
config: {
handler(newValue) {
this.initConfig();
},
immediate: true,
},
},
};
</script>
复制代码
可以看到 在表格内 我们分了三种情况
-
v-if="item.type === 'function'"
如果接口返回的内容需要我们解析出来并渲染到页面中 比如:0 代表 男 1 代表 女
-
v-else-if="item.type === 'operation'"
operation 表示操作栏
-
v-else
普通渲染文本
如果你项目中还有别的需求 可以继续添加类型判断
使用
<template>
<div class="videoQuert">
<div class="main">
<tableConfig
:config="table_config"
:tableData="dataList"
/>
</div>
<videoQuertdialog ref="videoQuertdialog"></videoQuertdialog>
</div>
</template>
<script>
import { matter, matterPage, matterExport } from "@api";
import { handleTime } from "@utils/date";
export default {
components: {
tableConfig: () => import("@com/jkTableConfig"),
videoQuertdialog: () =>
import("@views/Analysis/components/videoQuertdialog.vue"),
},
data() {
return {
// 表格数据
table_config: {
thead: [
{ label: "序号", prop: "index", width: "113" },
{ label: "通道名称", prop: "channelName" },
{
label: "标记类型",
prop: "matterStyleName",
},
{ label: "操作用户", prop: "userName" },
{ label: "描述", prop: "description", minWidth: "250x" },
{
label: "操作",
type: "operation",
actionButtons: [{ title: "查看录像" }],
callback: (row, title) => {
// console.log(row)
if (title) {
switch (title) {
case "查看录像":
return this.dialogShow(row);
}
}
},
},
],
},
formInline: {
startTime: handleTime(
new Date(new Date().setHours(0, 0, 0, 0)),
"yyyy-MM-dd HH:mm:ss"
),
endTime: handleTime(new Date(), "yyyy-MM-dd HH:mm:ss"),
matterType: null,
},
matterTypes: [],
userId: 0,
pageSize: 20,
pageIndex: 1,
dataList: [{}],
row: 0,
};
},
created() {
this.getMatterPage();
},
methods: {
async getMatterPage() {
await matterPage(
this.userId,
this.formInline.matterType === null ? 0 : this.formInline.matterType,
{
PageSize: this.pageSize,
PageIndex: this.pageIndex,
StartTime: this.formInline.startTime,
EndTime: this.formInline.endTime,
}
).then((res) => {
if (res.status == 200) {
this.row = res.message.count;
this.dataList = res.message.data;
} else {
this.$message({
message: `获取标记类型错误,http状态码:${res.status}`,
type: "warning",
});
}
});
},
//打开弹窗
dialogShow(row) {
this.$refs.videoQuertdialog.show(row);
},
},
};
</script>
复制代码
直接导入然后把 表格数据 dataList 和 表格配置信息table_config传入
<tableConfig :config="table_config" :tableData="dataList" />
复制代码
重点看下配置
table_config: {
thead: [
{ label: "序号", prop: "index", width: "113" },
{ label: "通道名称", prop: "channelName" },
{
label: "标记类型",
prop: "matterStyleName",
},
{ label: "操作用户", prop: "userName" },
{ label: "描述", prop: "description", minWidth: "250x" },
{
label: "操作",
type: "operation",
actionButtons: [{ title: "查看录像" }],
callback: (row, title) => {
// console.log(row)
if (title) {
switch (title) {
case "查看录像":
return this.dialogShow(row);
}
}
},
},
],
},
复制代码
这是我们定义的表单数据
其中:thead 包含头部数据
lable:表示表格头部名称
prop: 表示名称的字段
index: 表示表格的宽度
type: 特殊情况 这里我定义operation 表示这列是操作 actionButtons是个数组 里面title 表示的操作按钮的名称 callback 则是触发的回调
复制代码
callback: (row, title) => {
// console.log(row)
if (title) {
switch (title) {
case "查看录像":
return this.dialogShow(row);
}
}
},
复制代码
这里很灵活的可用 switch 判断触发的是那个按钮 然后调用对应的方法
总结:
第一次写文章 主要就是想锻炼下自己 难免写的不好 会慢慢改造 希望大家勿喷!