<template>
<div class="table-container">
<div class="table-box">
<el-table
class="table-height"
highlight-current-row
v-loading="loading"
:data="tableData" fit
:height="tableHeight"
:header-cell-style="headerStyle"
style="width: 100%" @row-click="rowClick" @selection-change="handleSelectionChange">
<el-table-column v-if="indexShow" type="index" align="center" label="序号">
</el-table-column>
<el-table-column v-if="isCheck" type="selection" align="center" :selectable="selectable" fixed>
</el-table-column>
<el-table-column v-for="(item, index) in tableHeader"
:key="index"
:label="item.label"
:prop="item.prop"
:sortable="item.oper || item.switch ? false : true"
:fixed="item.fixed"
:width="item.width"
:show-overflow-tooltip="showOverflowTooltip"
align="center">
<template slot-scope="scope">
<span v-if="item.oper">
<el-button v-for="(o, index) in item.oper"
v-hasBtn="o.hasBtn && typeof o.hasBtn == 'function' ? o.hasBtn(scope.row) : o.hasBtn"
v-show="o.isShowFun && typeof o.isShowFun == 'function' ? o.isShowFun(scope.row) : true"
:key="index"
:type="o.style"
:icon="o.icon"
:disabled="!o.disBtnFun ? (scope.row[o['prop']] == 1) : o.disBtnFun(scope.row)"
@click="o.clickFun(scope.row, scope.$index, tableData)"
size="small">
<template v-if="!o.formatDatas">{{ o.name }}</template>
<template v-else>
{{ o.formatDatas(scope.row) }}
</template>
</el-button>
</span>
<span v-if="item.switch">
<el-switch v-for="(o, index) in item.switch"
:key="index" @change="o.clickFun($event, scope.row)"
class="switchStyle"
:disabled="o.disSwitchFun ? o.disSwitchFun(scope.row) : false"
:active-value="scope.row[o['prop']] > 1 || scope.row[o['prop']] < 0 ? scope.row[o['prop']] : o.activeValue ? o.activeValue(scope.row) : o.active"
:inactive-value="scope.row[o['prop']] > 1 || scope.row[o['prop']] < 0 ? scope.row[o['prop']] : o.inactiveValue ? o.inactiveValue(scope.row) : o.inactive"
:active-text="o.activeText ? o.activeText(scope.row) : o.text"
:inactive-text="o.inactiveText ? o.inactiveText(scope.row) : o.intext"
:active-color="o.activeColor ? o.activeColor : '#13ce66'"
:inactive-color="o.inactiveColor ? o.inactiveColor : '#ff4949'"
v-model="scope.row[o['prop']]"
size="small"
>
</el-switch>
</span>
<!--formatData:自定义过滤器-->
<template v-else>
<template v-if="!item.formatDatas && !item.isEdit">{{ scope.row[item.prop] }}</template>
<template v-else-if="item.isEdit && item.inputType">
<el-input
v-if="item.inputType === 'input'"
v-show="scope.row.editFlag"
v-model="scope.row[item.prop]"
maxlength="50"
:placeholder="'请输入'+item.label">
</el-input>
<el-select
v-show="scope.row.editFlag"
v-if="item.inputType === 'select'"
v-model="scope.row[item.prop]"
placeholder="请选择">
<el-option
v-for="k in (typeof item.options == 'function' && item.options(scope.row) || [])"
:key="k.value"
:label="k.label"
:value="k.value">
</el-option>
</el-select>
<el-date-picker
v-show="scope.row.editFlag"
v-if="item.inputType === 'date'"
v-model="scope.row[item.prop]"
:valueFormat="scope.row.valueFormat"
:format="scope.row.format"
type="date"
placeholder="请选择日期">
</el-date-picker>
<span v-show="!scope.row.editFlag">
{{ item.formatDatas ? item.formatDatas(scope.row) : scope.row[item.prop] }}
</span>
</template>
<template v-else>
{{ scope.row | formatters(item.formatDatas) }}
</template>
</template>
</template>
</el-table-column>
</el-table>
</div>
<div class="page-box">
<pub-pagination v-if="pageFlag" class="right page-height"
:total="total"
:currentPage="pagesize"
:pageSizes="pageSizes"
:pageSize="limit"
:layout="layout"
@handleSizeChange="handleSizeChange"
@handleCurrentChange="handleCurrentChange">
</pub-pagination>
</div>
</div>
</template>
<script>
import PubPagination from './p-pagination'
export default {
components: {
PubPagination
},
props: {
// 是否初始化调用initData
isInitFlag: {
type: Boolean,
default: true
},
// 是否通过接口获取数据
isApiFlag: {
type: Boolean,
default: true
},
dataList: {
type: Array,
default: ()=>[]
},
// 表格高度
tableHeight: {
type: String,
default: '100%'
},
// 表格头部字段
tableHeader: {
type: Array,
default: function() {
return [];
}
},
headerStyle: {
type: Function,
default: function() {
return {
background:'#eef1f6',
color:'#606266'
}
}
},
// 复选框列flag
isCheck: {
type: Boolean,
default: false
},
// 序号列flag
indexShow: {
type: Boolean,
default: false
},
// 接口
api: {
type: Function,
default: ()=>{}
},
pageFlag: {在这里插入代码片
type: Boolean,
default: true
},
// 分页layout
layout: {
type: String,
default: 'slot, prev, pager, next, sizes, jumper'
},
// 绑定复选框prop
isDisCheck: {
type: Function,
default: () => {}
},
// 个数选择器
pageSizes: {
type: Array,
default: () => {
return [10, 20]
}
},
// 是否超出省略
showOverflowTooltip: {
type: Boolean,
default: () => {
return true
}
}
},
created() {
if(!this.pageFlag) {
this.limit = 999;
}
this.limit = this.pageSizes[0];
this.initData();
// console.log(this.tableHeight);
},
filters: {
formatters(val, func) {
if(typeof func !== 'function') {
return val;
}
return func(val);
}
},
data () {
return {
tableData: [],
limit: 10, // 每页条数
pagesize: 1, // 页码
// pageSizes: [10, 20],
total: 0,
loading: true, // 表格加载状态
queryParams: {} // 查询条件
};
},
watch: {
dataList: {
handler(n, o) {
this.tableData = n;
},
deep: true
}
},
methods: {
initData() { // 初始化数据
if(!this.isApiFlag) {
this.loading = false;
this.tableData = this.dataList;
return;
}
if (this.isInitFlag) {
this.loading = true;
this.api({
"pageNum": this.pagesize,
"pageSize": this.limit
}).then(res=> {
this.loading = false;
let data = res && res.data;
this.$emit('dataformat', data)
this.tableData = data.list;
this.total = data.total;
if (data.total == 0) {
this.pagesize = 0;
}
}).catch(err=> {
this.loading = false;
})
} else {
this.loading = false;
}
},
queryTable(obj) { // 查询条件
this.queryParams = obj;
this.resetPage();
this.updateList();
},
resetTable() {
// 重置条件
this.queryParams = {};
this.resetPage();
this.updateList();
},
resetPage() { // 重置页码
if(!this.pageFlag) {
this.limit = 999;
this.pagesize = 1;
return;
}
this.pagesize = 1;
this.limit = this.pageSizes[0];
},
updateList() { // 更新数据
let params = Object.assign({
"pageNum": this.pagesize,
"pageSize": this.limit
}, this.queryParams);
this.loading = true;
this.api(params).then((res)=> {
this.loading = false;
let data = res && res.data;
this.$emit('dataformat', data)
this.tableData = data.list;
this.total = data.total;
if (data.total == 0) {
this.pagesize = 0;
}
}).catch(err=> {
this.loading = false;
})
},
rowClick(val) { // 行点击事件
this.$emit('rowClick', val);
},
handleSelectionChange(val) { // 选择的内容
this.$emit('selectData', val);
},
handleSizeChange(val) { // 每页多少条
this.limit = val;
this.updateList();
},
handleCurrentChange(val) { // 当前页码
this.pagesize = val;
this.updateList();
},
selectable(row, index) {
let flag = this.isDisCheck(row);
if (flag) {
return false;
} else {
return true;
}
}
}
}
</script>
<style lang='less' scoped>
/deep/ .switchStyle .el-switch__label {
position: absolute;
display: none;
color: #fff;
}
/deep/ .switchStyle .el-switch__label--left {
z-index: 9;
left: 10px;
}
/deep/ .switchStyle .el-switch__label--right {
z-index: 9;
left: -2px;
}
/deep/ .switchStyle .el-switch__label.is-active {
display: block;
}
/deep/ .switchStyle.el-switch .el-switch__core,
.el-switch .el-switch__label {
width: 70px !important;
}
.table-container {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
flex: 1 0 auto;
border-radius: 20px;
& > .table-box {
height: 91% !important;
padding: 12px 23px 0 23px;
/deep/ .el-table td {
padding: 8px 0;
}
/deep/ .el-table th {
padding: 12px 0;
}
/deep/ .el-table::before, /deep/ .el-table__fixed::before {
background: none;
}
/deep/ .el-input__inner {
height: 32px;
line-height: 32px;
}
/deep/ .el-input__icon {
line-height: 32px;
}
}
.page-box {
height: 6%;
padding-top: 0.10rem;
font-size: 0.16rem;
}
}
.right {
text-align: right;
// margin: 20px 0;
}
/deep/ .el-table .cell.el-tooltip {
line-height: 33px;
}
</style>
vue表格封装
最新推荐文章于 2024-10-10 11:26:01 发布