一.组件调用
1.引入组件
import cuTable from "@/components/cu-table/cu-table";
2.引入配置文件
import { paramData } from "./config/common.js";
3.template、script写法
<script> export default { components: { cuTable },
data() {
return {
paramData: paramData,
}
},
methods: {
search(params) {
this.$refs.cuTable.curPage = 1;
this.$refs.cuTable.getTableData({ ...params });
},
}
}
</script>
<template>
<cu-table ref="cuTable" :param="paramData">
<template #action="{ data }"></template>
</cu-table>
</template>
4.在js文件中进行配置json
// 绩效考核
export const paramData1 = {
border: true,
getDataUrl: "hr/performanceEvaluationScore/assessmentList",
methodFun: "post",
noGetData: true,
tableHeader: [
{
title: `标题中文`,
align: "center",
field: "英文字段",
width: 100,
},
{
title: `操作`,
align: "center",
width: 120,
slotName: "action", // 插槽
},
],
};
二.封装组件
<template>
<div class="table_wrap">
<slot name="header"></slot>
<el-table
ref="table"
v-loading="loading"
:data.sync="tableData"
highlight-current-row
:border="param.border"
@row-click="rowClick"
:span-method="spanmethod"
:row-class-name="tableRowClassName"
:empty-text="emptyText"
:tree-props="{ children: 'children' }"
@selection-change="selectChange"
@select="selectFun"
@select-all="selectAll"
@sort-change="sortChange"
:default-sort="defaultSort"
>
<el-table-column
v-if="param.selection"
type="selection"
width="55"
align="center"
:selectable="selecTableChoice"
></el-table-column>
<!-- <el-table-column type="selection" width="55" :selectable="selecTableFun" v-if="param.selection" align="center"></el-table-column> -->
<el-table-column
v-if="param.radio && !param.selection"
width="55"
align="center"
>
<template slot-scope="scope">
<el-radio
v-model="activeRowIndex"
class="radio_column"
:label="scope.$index"
@change.native="
() => {
activeRowIndex = scope.$index;
selecTableFun(scope.row);
}
"
></el-radio>
</template>
</el-table-column>
<el-table-column
v-if="!param.indexNum"
type="index"
label="序号"
width="60"
align="center"
>
<template slot-scope="scope">
{{ orderNumber(scope.$index) }}
</template>
</el-table-column>
<!--<!– prop: 字段名name, label: 展示的名称, fixed: 是否需要固定(left, right), minWidth: 设置列的最小宽度(不传默认值), oper:–>
<!–是否有操作列–>
<!–oper.name: 操作列字段名称, oper.clickFun: 操作列点击事件, formatData: 格式化内容 –>-->
<el-table-column
v-for="(th, key) in param.tableHeader"
:key="key"
:prop="th.field"
:label="th.title"
:fixed="th.fixed"
:show-overflow-tooltip="!th.tooltip"
:min-width="th.width"
:sortable="th.sortable"
:align="th.align ? th.align : 'center'"
>
<!--加入template主要是对列的操作,dic表示字典,link表示详情,button表示按钮操作,swich表示开关-->
<template slot-scope="scope">
<div class="rowClass_1">
<slot
v-if="th.slotName"
:name="th.slotName"
:data="{ row: scope.row, index: scope.$index, th: th }"
></slot>
<span v-else-if="th.oper && th.oper.name == 'dicArray'">
<template v-for="item in th.oper.options">
<span
v-if="
item[th.oper.valueKey || 'value'] == scope.row[th.field]
"
>{{ item[th.oper.labelKey] || item.label }}</span
>
</template>
</span>
<span v-else-if="th.oper && th.oper.name == 'dic'">{{
scope.row[th.field]
}}</span>
<!-- <span v-else-if="th.oper && th.oper.name == 'dic'" :style="{color:th.oper.styleColor && th.oper.styleColor[scope.row[th.field]]}">{{ scope.row[th.field] | filterDic(th.oper) }}</span> -->
<span v-else-if="th.oper && th.oper.name == 'area'">{{
scope.row[th.field] | filterDic(th.oper.fun)
}}</span>
<span v-else-if="th.oper && th.oper.name == 'timeStamp'">{{
scope.row[th.field]
| filterTimeFormat(
th.oper.timeFormat
? th.oper.timeFormat
: "YYYY-MM-DD HH:mm:ss"
)
}}</span>
<span v-else-if="th.oper && th.oper.name == 'link'">
<!-- <span @click="th.oper.clickFun(scope.row)" :class='["link",th.oper.color=="1" ? "active" : ""]'>{{ scope.row[th.field] }}</span> -->
<span
:class="handleEvalStatuslist(th.oper.color)"
@click="th.oper.clickFun(scope.row)"
>{{ scope.row[th.field] }}</span
>
</span>
<!-- 表格中按钮添加了flag和icon ,flag用于自定义class名修改样式,icon用于按钮图标。-->
<!-- 公共按钮 编辑flag:update,icon:bianji 删除 flag:delete,icon:shanchu -->
<span
v-else-if="th.oper && th.oper.name == 'button'"
style="display: inline"
class="table_oper_btn"
>
<span
v-for="(o, key) in th.oper.btnObj"
:key="key"
v-show="!o.condition || o.condition(scope.row, scope.$index)"
>
<el-button
v-hasPermi="o.hasPermi"
size="mini"
:class="buttonText(scope.row, o).flag"
@click="o.clickFun(scope.row, scope.$index)"
>
<span
style="display: inline"
v-text="buttonText(scope.row, o).name"
></span>
</el-button>
<slot
v-if="o.slotName"
:name="o.slotName"
:data="{ row: scope.row, th: th }"
></slot>
</span>
</span>
<span
v-else-if="th.oper && th.oper.name == 'switch'"
style="min-width: 60px; display: inline-block"
>
<el-switch
v-model="scope.row[th.field]"
:active-value="th.oper.flag.on ? th.oper.flag.on : flag.on"
:inactive-value="th.oper.flag.off ? th.oper.flag.off : flag.off"
:active-text="th.oper.activeText ? th.oper.activeText : '启用'"
:inactive-text="
th.oper.inactiveText ? th.oper.inactiveText : '停用'
"
:disabled="th.oper.disabled"
:width="60"
@change="th.oper.clickFun(scope.row)"
>
</el-switch>
</span>
<span v-else>{{
scope.row[th.field] ? scope.row[th.field] : "-"
}}</span>
</div>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination
:pager-count="5"
@current-change="currentChange"
@size-change="sizeChange"
:current-page="curPage"
:page-size="maxSize"
:page-sizes="[10, 20, 30, 40, 50]"
:total="recordCnt"
v-if="!param.pagination"
layout="total, sizes, prev, pager, next, jumper"
background
>
</el-pagination>
</div>
</div>
</template>
<script>
import request from "@/utils/request";
import moment from "moment";
import { tableData } from "../../views/pm/ledgerInfo/info/config";
export default {
props: {
spanmethod: {
type: Function,
default: function () {
return {
rowspan: 1,
colspan: 1,
};
},
},
param: {
noParamsMap: {
type: Boolean,
default: function () {
return false;
},
},
getDataUrl: {
type: String,
default: function () {
return "";
},
},
methodFun: {
type: String,
default: function () {
return "get";
},
},
getDataParam: {
type: Object,
default: function () {
return {};
},
},
tableHeader: {
type: Array,
default: function () {
return [];
},
},
noGetData: {
type: Boolean,
},
where: {
type: Object,
default: function () {
return {};
},
},
tableRowClassNameFun: {
type: Function,
default: function () {
return false;
},
},
},
pagination: {
type: Boolean,
},
summaryMethod: {
type: Function,
default: function () {
return function () {};
},
},
selecTableFun: {
type: Function,
},
mouseEnter: {
type: Function,
},
mouseLeave: {
type: Function,
},
dataConversion: {
type: Function,
},
otherType: {
type: String,
},
defaultSort: {
type: Object,
},
emptyText:{
type: String,
default:"",
}
},
data() {
return {
searchFormData: {},
activeRowIndex: "",
loading: false,
curPage: 1,
maxSize: 10,
disabled: false,
nextPage: "",
prePage: "",
recordCnt: 0,
tableData: [],
tableHeader: this.param.tableHeader,
flag: {
on: 0,
off: 1,
},
selectRow: [],
linkcolor: true,
selecTableChoice1: true,
};
},
filters: {
filterTimeFormat: function (val, timeFormat) {
return moment(val).format(timeFormat);
},
},
computed: {
interval: function () {
let total = this.curPage * this.maxSize;
if (this.curPage == 1) {
return this.curPage + "-" + total;
} else {
let start = total - this.maxSize + 1;
if (this.recordCnt < total) {
total = this.recordCnt;
}
return start + "-" + total;
}
// return this.curPage
},
buttonText: function () {
return function (row, o) {
if (o && o.funText && o.funText(row)) {
return o.funText(row);
}
return o;
};
},
},
watch: {
tableData(val) {
this.$nextTick(() => {
// 多选框根据字段checked默认勾选选中
this.setDefaultChecked(val);
});
},
},
created() {
this.searchFormData = {};
let that = this;
this.param.tableHeader.filter(function (item) {
// let type, url, index;
let url;
if (item.oper && item.oper.name == "dic") {
if (item.oper.realTimeUrl) {
// 表格列数据需实时请求
url = item.oper.realTimeUrl;
that.common.realTimeRequest(
url,
item.oper.type,
item.oper.dicDataConversion
);
} else {
// 表格列数据从字典获取
url = that.$urlList.common.dic;
that.common.getDic(url, item.oper.type);
}
}
});
let self = this;
setTimeout(() => {
if (!self.param.noGetData) {
self.getTableData();
}
}, 500);
},
mounted() {
this.EventBus.$off("searchTableData");
this.EventBus.$on("searchTableData", (parmas) => {
// if (parmas.type === 0) {
this.curPage = 1;
// }
this.getTableData(parmas);
});
},
destroyed() {
/**
* Bus这个事件需要解绑,要不然路由切换回缓存之前的调用
*/
// this.EventBus.$off('searchTableData');
},
methods: {
selecTableChoice(row) {
if (this.$parent.selecTableChoice) {
// this.$emit('selecTableChoice',row)
if (row.status == 1 || row.status == 2 ) {
return true;
} else {
return false;
}
} else {
return true;
}
},
sortChange(e) {
this.$emit("sortChange", e);
},
rowClick(e) {
this.$emit("row-click", e);
},
tableRowClassName({ row }) {
if (this.param.tableRowClassNameFun) {
return this.param.tableRowClassNameFun(row);
}
},
// 设置默认选中多选框
setDefaultChecked(rows) {
if (rows.length > 0) {
rows.forEach((row) => {
if (row.checked) {
this.$refs.table.toggleRowSelection(row, true);
this.selectRow.push(row);
}
});
}
},
orderNumber(index) {
if (this.curPage > 1) {
return this.maxSize * (this.curPage - 1) + index + 1;
} else {
if (index < 9) {
return index + 1;
} else {
return index + 1;
}
}
},
firstPage() {
this.curPage = 1;
this.getTableData();
},
lastPage() {
let val = this.recordCnt / this.maxSize;
if (val < 1) {
val = 1;
} else {
val = Math.ceil(val);
}
this.curPage = val;
this.getTableData();
},
currentChange(val) {
this.curPage = val;
this.getTableData();
console.log("currentChange", val);
this.$emit("handleCurrentPage", val);
},
sizeChange(val) {
this.maxSize = val;
this.curPage = 1;
this.getTableData();
this.$emit("handlePageSize", val);
},
resetPageSize() {
this.maxSize = 10;
this.curPage = 1;
this.getTableData();
},
getTableData(form) {
let paramData = {
pageNum: this.curPage,
pageSize: this.maxSize,
};
// 没有分页不需要 初始分页参数
if (this.param.pagination) {
paramData = {};
}
// 遍历检索条件form对象,每一项添加在请求报文params中
if (form) {
this.searchFormData = form;
paramData = { ...paramData, ...this.searchFormData };
}
// console.log("where", this.param.where);
if (this.param.where) {
paramData = { ...paramData, ...this.param.where };
}
// 根据id判断在哪个菜单中,获取对应的json路径对象
let url = this.param.getDataUrl;
// 判断页面是否有配置表格的请求接口路径,若没配默认用getpage。
// 配置接口路径适用于详情等弹框页面的表格
// if (!this.param.getDataUrl) {
// url = this.$urlList.business[this.param.bussName].getPage;
// } else {
// url = this.param.getDataUrl;
// }
this.loading = true;
paramData = { ...this.searchFormData, ...this.param.where, ...paramData };
this.curPage = paramData.pageNum;
let config = {};
if (this.param.paramsHaveArray) {
config.haveArray = true;
}
this.param.methodFun = this.param.methodFun
? this.param.methodFun
: "get";
let fun =
this.param.methodFun == "get"
? request({ url: url, method: "get", params: paramData })
: request({ url: url, method: "post", data: paramData });
fun
.then((res) => {
// 需要数据处理时传入此方法
if (res.code == 200) {
if (this.dataConversion) {
res = this.dataConversion(res);
}
this.tableData = res.data.rows;
this.recordCnt = res.data.total;
if (res.other && this.param.otherType) {
this.totalLine(res.other);
}
if (res.data.rows.length == 0 && this.curPage != 1) {
this.curPage = this.curPage - 1;
this.getTableData(this.searchFormData);
return;
}
this.$emit("getTableData", res);
}
})
.finally(() => {
this.loading = false;
});
},
//合计增加字段
totalLine(total) {
//是否增加"合计"行
let tatalObj = {
//收款合计
contract: {
contractName: "合计",
totalGetPrice: total != null ? total.total.totalGetPrice : "",
amount: total.total != null ? total.amount : "",
totalOpenPrice: total != null ? total.total.totalOpenPrice : "",
},
attendance: {
userName: "合计",
amount: total != null ? total.amount : "",
totalOpenPrice: total != null ? total.totalOpenPrice : "",
totalGetPrice: total != null ? total.totalGetPrice : "",
},
ticketList: {
code: "合计",
totalGetPrice: total != null ? total.total.totalGetPrice : "",
invoicingPrice: total != null ? total.total.invoicingPrice : "",
},
payeeList: {
inCode: "合计",
getPrice: total != null ? total.total : "",
},
};
this.$nextTick(() => {
this.tableData.push(tatalObj[this.param.otherType]);
});
},
selectChange(selection) {
this.$emit('selecTableChoice',selection);
},
selectFun(selection) {
// selectFun(selection, row) {
this.selectRow = selection;
},
selectAll(selection) {
this.selectRow = selection;
},
//传值设置单独td的字体颜色
handleEvalStatuslist(val) {
if (val == 1) {
return "linkcolor";
} else {
return " ";
}
},
// ,selectionChange(selection) {}
},
};
</script>
<style lang="scss" scoped>
.table_oper_btn :not(:last-child) {
position: relative;
&::after {
content: " ";
// clear:both;
// display: inline-block;
position: absolute;
right: 0;
top: 5px;
height: 8px;
width: 1px;
background: #e4e4e4;
}
}
.table_wrap {
font-size: 14px;
// height: calc(100vh - 229px);
color: #303133;
// padding: 0 30px;
display: flex;
flex-direction: column;
justify-content: space-between;
.el-table {
// min-height: 480px;
border-radius: 4px 4px 0 0;
// overflow: auto;
margin-bottom: 10px;
.cell {
font-weight: bold;
}
.el-table__row {
height: 40px;
td {
.el-radio.radio_column ::v-deep.el-radio__label {
display: none;
}
div {
overflow: hidden;
text-overflow: ellipsis;
}
span {
font-size: 12px;
font-weight: 400;
}
.el-button {
border: none;
background: transparent;
// color: $main-color;
}
.delete_btn {
// color: $error-color;
color: #d9001b;
}
.edit_btn {
color: #0e73ee;
}
.edits_btn {
color: #0e73ee;
}
.drawer_btn {
color: #0e73ee;
}
.cancel_btn {
color: #0e73ee;
}
}
}
}
.pagination {
display: flex;
justify-content: flex-end;
}
.page.el-pagination {
font-weight: normal;
text-align: right;
// color: $content-text-color;
margin-bottom: 10px;
.records {
margin-right: 22px;
.high_light {
// color: $main-color;
min-width: 0;
padding: 0 3px;
}
}
.first_page,
.last_page {
display: inline-block;
cursor: pointer;
height: 30px;
padding: 0;
border: 1px solid #e4e7ee;
border-radius: 4px;
padding: 0 10px;
}
.last_page {
margin-left: 10px;
}
::v-deep.el-pagination__jump {
margin-left: 20px;
}
.first_page:hover,
.last_page:hover {
// color: $main-color;
}
::v-deep button,
::v-deep .el-pager li {
min-width: 30px;
height: 30px;
padding: 0;
border: 1px solid #e4e7ee;
border-radius: 4px;
margin: 0 4.5px;
}
::v-deep li.active {
color: #fff;
// background-color: $main-color;
cursor: default;
}
}
}
//1
.active {
color: #3366ee;
}
.linkcolor {
color: #3366ee;
cursor: pointer;
}
</style>