后台管理的表格封装,高效搬砖!
直接可以拿来用,或者是自己可以改改,绝对适用大部分后台的表格,再次做个记录,也方便自己以后方便随取随用... , el-pagination其中有一个分切切换,就是简单封装一下引入就行了
HTML部分
<template>
<div class="base-table" v-loading="$attrs.loading">
<el-table
ref="baseTable"
:data="$attrs.data"
:stripe="$attrs.stripe !== false"
style="width: 100%"
tooltip-effect="light"
v-bind="$attrs"
v-on="$listeners"
:row-key="rowKey"
>
<el-table-column
v-if="showSelection || $attrs.selection"
label="选择"
type="selection"
width="55"
:reserve-selection="true"
:selectable="selectable"
/>
<el-table-column
v-if="showIndex"
:fixed="indexFixed"
:index="indexMethod"
:label="indexLabel"
:type="type"
:width="indexWidth"
/>
<el-table-column
v-for="(item, idx) in tableConf"
:key="idx"
:fixed="item.fixed || false"
:label="item.label"
:width="item.width || ''"
:min-width="item.minWidth || ''"
:max-width="item.maxWidth || ''"
:align="item.align"
:type="item.type"
:show-overflow-tooltip="
typeof item.showOverflowTooltip === 'undefined'
? true
: item.showOverflowTooltip
"
>
<template slot-scope="scope">
<span v-if="item.dic">{{
item.dic[scope.row[item.prop]] || "--"
}}</span>
<span v-else-if="item.rich" v-html="scope.row[item.prop]" />
<span v-else-if="item.func">{{
item.func(scope.row, item.prop)
}}</span>
<!-- 中间自定义列 -->
<span v-else-if="item.selfDefine || item.custom">
<slot
name="column"
:data="scope.row"
:index="scope.$index"
:prop="item.prop"
:scope="scope"
></slot>
</span>
<span v-else-if="$slots[item.prop]">
<slot
:name="item.prop"
:data="scope.row"
:index="scope.$index"
:scope="scope"
/>
</span>
<span v-else-if="$scopedSlots[item.prop]">
<slot
:name="item.prop"
:data="scope.row"
:index="scope.$index"
:scope="scope"
/>
</span>
<span v-else-if="item.type === 'index'">{{
indexMethod(scope.$index)
}}</span>
<span v-else>{{ formatValue(scope.row, item.prop) }}</span>
</template>
</el-table-column>
<!-- 自定义其他列 -->
<slot></slot>
<!-- 自定义操作列-->
<el-table-column
v-if="operate"
:fixed="operateFixed"
:label="operateLabel"
:width="operateWidth"
:align="operateAlign"
>
<template slot-scope="scope">
<slot
:data="scope.row"
:index="scope.$index"
:scope="scope"
name="edit"
/>
<el-button
v-if="useDelete"
type="text"
class="table-delete-btn-text"
@click="onDelete(scope.row, scope.$index)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<div v-if="page" :class="{ 'hidden-pagination': hiddenPagination }">
<ty-page
v-if="usePage"
:hide-on-single-page="total < 15"
:current-page="+queryInfo.page"
:page-size="+queryInfo.size"
:total="+total"
@current-change="val => $emit('page-change', val)"
@size-change="val => $emit('size-change', val)"
/>
<el-pagination
v-else
:current-page="+queryInfo.page"
:hide-on-single-page="true"
:page-size="+queryInfo.size"
:total="+total"
layout="total, prev, pager, next"
@current-change="val => $emit('page-change', val)"
/>
</div>
</div>
</template>
JavaScript部分
export default {
name: "BaseTable",
components: { TyPage },
props: {
// 表格配置项,非必填
hiddenPagination: {
type: Boolean,
default: false
},
tableConf: Array,
type: {
type: String,
default: "index"
},
showSelection: {
type: Boolean,
default: false
},
rowKey: {
type: String,
default: "id"
},
selectable: {
type: Function,
default: function() {
return true;
}
},
// 序号相关
showIndex: {
type: Boolean,
default: true
},
indexFixed: {
type: [Boolean, String],
default: true
},
indexLabel: {
type: String,
default: "序号"
},
indexWidth: {
type: [String, Number],
default: "80"
},
// 是否提供删除功能,删除功能将解决分页查询问题,需要与分页共存
useDelete: {
type: Boolean,
default: false
},
deleteTitle: {
type: String,
default: "操作提示"
},
deleteTips: {
type: String,
default: "确定执行删除操作?"
},
// 分页相关
// 是否使用分页
page: {
type: Boolean,
default: true
},
total: {
type: Number
},
// 查询信息,分页必传,尤其是分页参数
queryInfo: {
type: Object,
default: () => ({})
},
// 自定义操作列
operateAlign: {
type: String,
default: "left"
},
operateLabel: {
type: String,
default: "操作"
},
// 操作列是否固定,可选值(true、false、left、right)
operateFixed: {
type: [Boolean, String],
default: "right"
},
operateWidth: {
type: String,
default: "150"
},
// 操作权限
operate: {
type: Boolean,
default: false
}
},
computed: {
usePage() {
const sizeChangeFn =
this.$listeners["size-change"] || this.$listeners.sizeChange;
return !!sizeChangeFn;
}
},
methods: {
formatValue(row, prop) {
if (prop === "") return prop ?? "--";
if (prop?.includes(".")) {
const args = prop.split("."),
len = args.length - 1;
let value = "",
x = 0;
try {
while (x <= len) {
if (row[args[x]]) {
value = row[args[x]];
value = value[args[++x]];
} else {
x++;
}
}
} catch (e) {
console.log(e);
value = "";
}
return value ?? "--";
}
return row?.[prop] ?? "--";
},
getBaseTable() {
return this.$refs.baseTable;
},
indexMethod(idx) {
if (this.page && this.queryInfo.page && this.queryInfo.size) {
return idx + 1 + (this.queryInfo.page - 1) * this.queryInfo.size;
} else {
return idx + 1;
}
},
async onDelete(row, index) {
try {
await operateDialog({
title: this.deleteTitle,
message: this.deleteTips
});
this.$emit("delete", row, index);
} catch (e) {
console.log("onDelete -> e", e);
if (e === "cancel") {
this.$emit("delete-cancel", row, index);
}
}
}
}
};
分页器封装
<template>
<el-pagination
layout="total, prev, pager, next, sizes"
:page-sizes="pageSizes"
v-bind="$attrs"
v-on="$listeners"
/>
</template>
<script>
export default {
name: "TyPage",
computed: {
pageSizes() {
return pageSizes;
}
}
};
</script>