1、封装 Table.vue:
<template>
<div id="ETable">
<el-table
ref="Table"
:data="data"
v-bind="$attrs"
v-on="$listeners"
>
<el-table-column
v-if="selectable"
type="selection"
v-bind="getSelectionBind()"
>
</el-table-column>
<el-table-column
v-if="!noIndex"
type="index"
v-bind="getIndexBind()"
></el-table-column>
<el-table-column
v-for="(item,index) in items"
:key="index"
v-bind="getBind(item)"
>
<template
v-if="$scopedSlots[item.prop]"
#default="scope"
>
<slot
:name='item.prop'
:item='item'
v-bind="scope"
/>
</template>
<template
v-else-if="item.type"
#default="{row}"
>
<component :is="item.type" v-bind="item.bind(row[item.prop])"/>
</template>
</el-table-column>
<el-table-column
v-if="$scopedSlots.default"
v-bind="getOperaBind()"
#default="scope"
>
<slot v-bind="scope" />
</el-table-column>
<el-empty
v-if="!disEmpty"
slot="empty"
description="暂无数据"
></el-empty>
</el-table>
<el-pagination
v-if="page"
v-bind="page"
@size-change="_c_size_change"
@current-change="_c_page_change"
/>
</div>
</template>
<script>
import * as _ from "lodash";
let config = {
defIndexBind: { label: "序号", width: "80px", align: "center" },
defOperaBind: { label: "操作", width: "200px", align: "center" },
selectionBind: { width: "50px" },
defBind: { align: "center", }
}
export default {
config,
props: {
data: Array,
items: Array,
page: Object,
noIndex: Boolean,
selectable: Boolean,
operaBind: Object,
indexBind: Object,
selectionBind: Object,
disEmpty: Boolean
},
mounted() {
this.$nextTick(function () {
this.setColSpan();
});
},
methods: {
// 暂时只支持单层的表头合并,多层的后面再说
setColSpan() {
let cells = this.$el.getElementsByClassName("el-table__header")[0].rows[0].cells;
if (!cells) return;
this.items?.forEach((item, index) => {
let i = this.noIndex ? index : index + 1;
if (item.colSpan === 0) {
cells[i].style.display = "none";
} else {
cells[i].colSpan = item.colSpan || 1;
}
});
},
//----------普通方法-----------
clearSelection() {
this.$refs.Table.clearSelection();
},
toggleRowSelection() {
this.$refs.Table.toggleRowSelection.apply(this, [...arguments]);
},
toggleRowsSelection(rows, flag) {
this.$refs.Table.clearSelection();
rows?.forEach((row) => {
this.$refs.Table.toggleRowSelection(row, flag);
});
},
getOperaBind() {
let bind = this.operaBind || {};
let def = _.cloneDeep(config.defOperaBind)
return _.merge(def, bind);
},
getIndexBind() {
let bind = this.indexBind || {};
let def = _.cloneDeep(config.defIndexBind)
return _.merge(def, bind);
},
getSelectionBind() {
let bind = this.selectionBind || {};
let def = _.cloneDeep(config.selectionBind)
return _.merge(def, bind);
},
getBind(item) {
let def = _.cloneDeep(config.defBind)
return _.merge(def, item);
},
//----------点击事件-----------
_c_size_change(val) {
this.page.pageSize = val;
this.$emit("page-change", this.page.pageNo);
},
_c_page_change(val) {
this.$emit("page-change", val);
},
//----------接口方法-----------
},
};
</script>
<style lang="scss">
.mycell, .mycell .cell{
padding: 0!important
}
</style>
2、用法:
<template>
<div>
<ETable
:data="tableData"
:items="items"
height="70vh"
border
:page.sync="page"
@page-change="_c_page_change">
<template #name="{row, item}">
自定义:<el-tag>{{row[item.prop]}}</el-tag>
</template>
<template #default="{row, item}">
<EBtn mode="detail" @click="_c_add"/>
<EBtn mode="update" @click="_c_update(row)"/>
<EBtn mode="delete" @click="_c_delete"/>
</template>
</ETable>
</div>
</template>
<script>
import crud_mixin from '@/mixins/crud_mixin.js'
export default {
mixins: [crud_mixin],
data() {
let _this = this
return {
tableData: [
{
id: 10201,
created_at: "2022-05-23T09:52:44.655+08:00",
updated_at: "2022-05-23T10:01:25.571+08:00",
is_deleted: 0,
name: "张三",
age: 21,
sex: 1,
org_id: 57,
detail: [
{ name: '情况1' },
{ name: '情况2' },
],
address: "111",
manager_name: "王sir",
manager_id: 25,
tel: "13451820534",
},
{
id: 10177,
created_at: "2022-04-06T11:21:10.794+08:00",
updated_at: "2022-04-06T11:30:50.51+08:00",
is_deleted: 0,
name: "姓名",
age: 21,
sex: 0,
org_id: 52,
detail: [
{ name: '情况1' },
{ name: '情况2' },
],
address: "22",
manager_name: "小委",
manager_id: 30,
tel: "13451820538",
},
{
id: 10175,
created_at: "2022-04-01T16:04:42.217+08:00",
updated_at: "2022-04-01T16:07:49.398+08:00",
is_deleted: 0,
name: "奥特曼11",
age: 9991,
sex: 1,
org_id: 2,
detail: [
{ name: '情况1' },
{ name: '情况2' },
],
address: "M781",
manager_name: "哥斯拉1",
manager_id: 200,
tel: "1234561",
},
{
id: 10171,
created_at: "2022-03-14T10:34:12+08:00",
updated_at: "2022-03-14T10:34:12+08:00",
is_deleted: 0,
name: "姚春华",
age: 1981,
sex: 1,
detail: [
{ name: '情况1' },
{ name: '情况2' },
],
address: "沙家圩村星月花园49-1506",
tel: "18862953186",
},
{
id: 10170,
created_at: "2022-03-14T10:34:12+08:00",
updated_at: "2022-03-14T10:34:12+08:00",
is_deleted: 0,
name: "顾金水",
age: 1969,
sex: 1,
detail: [
{ name: '情况1' },
{ name: '情况2' },
],
address: "源兴社区居委会源兴花苑8-103",
tel: "18862931462",
},
{
id: 10169,
created_at: "2022-03-14T10:34:12+08:00",
updated_at: "2022-03-14T10:34:12+08:00",
is_deleted: 0,
name: "姜美香",
age: 1967,
sex: 0,
detail: [
{ name: '情况1' },
{ name: '情况2' },
],
address: "源兴社区居委会源兴花苑9-204",
tel: "18862931462",
},
{
id: 10168,
created_at: "2022-03-14T10:34:12+08:00",
updated_at: "2022-03-14T10:34:12+08:00",
is_deleted: 0,
name: "施兴华",
age: 1958,
sex: 1,
detail: [
{ name: '情况1' },
{ name: '情况2' },
],
address: "源兴社区居委会源兴花苑41-402",
tel: "18862931462",
},
{
id: 10167,
created_at: "2022-03-14T10:34:12+08:00",
updated_at: "2022-03-14T10:34:12+08:00",
is_deleted: 0,
name: "黄聪明",
age: 1957,
sex: 1,
detail: [
{ name: '情况1' },
{ name: '情况2' },
],
address: "朝阳社区四圩桥村8组",
tel: "15996582978",
},
{
id: 10166,
created_at: "2022-03-14T10:34:12+08:00",
updated_at: "2022-03-14T10:34:12+08:00",
is_deleted: 0,
name: "胡顺英",
age: 1965,
sex: 0,
detail: [
{ name: '情况1' },
{ name: '情况2' },
],
address: "朝阳社区四圩桥村一组",
tel: "15996582978",
},
{
id: 10165,
created_at: "2022-03-14T10:34:12+08:00",
updated_at: "2022-03-14T10:34:12+08:00",
is_deleted: 0,
name: "陈圣珍",
age: 1943,
sex: 0,
detail: [
{ name: '情况1' },
{ name: '情况2' },
],
address: "朝阳社区朝阳花苑21-302",
tel: "15996582978",
},
],
items: [
{ prop: "name", label: "弱势群体人员姓名", colSpan: 0 },
{
prop: "age",
label: "出生年份",
type: 'ETag', // 这是自己封装的组件名称
bind:val => ({
text: val+'',
effect: 'plain',
})
},
{
prop: "sex",
label: "性别",
type: 'el-image',
bind:value => {
let src = {
1: require(`@/assets/images/boy.png`),
0: require(`@/assets/images/girl.png`),
}[value] || require(`@/assets/images/unknown.png`)
return {
src,
'preview-src-list': [src],
style:{
width: '40px',
}
}
}
},
{
prop: "address",
label: "住址",
formatter(row, col, value){
return value + '111'
}
},
{
prop: "detail",
label: "具体情况",
'class-name': 'mycell',
type: 'ECellList', // 这是自己封装的组件名称
bind: value => ({
data: value,
getItemText: (item, index) => (index+1) +'、'+ item.name
})
},
{ prop: "manager_name", label: "帮扶责任人" },
{ prop: "tel", label: "帮扶责任人联系电话" },
],
};
},
mounted() {},
methods: {
},
};
</script>
<style></style>
3、效果:
4、一般表格会用到crud_mixin.js:
import * as _ from 'lodash'
export default {
data() {
return {
page: {
pageNo: 1,
pageSize: 10,
total: 0,
pageSizes: [10, 20, 30, 40],
layout: "total, sizes, prev, pager, next, jumper",
pagerCount: 5,
background: true,
},
isEditDialogVisible: false,
isAdd: true,
loading:false,
curRow: null,
}
},
watch:{
'page.pageNo'(n, o){
this.page['current-page'] = n
}
},
created(){
},
mounted(){
},
methods: {
_m_tip(msg){
this.$message.success(msg);
this.isEditDialogVisible = false;
this._c_query();
},
_c_query() {
this.$set(this.page, 'pageNo', 1)
this._i_query();
},
_c_add(row){
this.$set(this, 'editForm', this.$options.data().editForm)
this.isAdd=true;
this.isEditDialogVisible=true
this.curRow = row
},
_c_update(row) {
this.editForm = _.cloneDeep(row);
this.isAdd = false;
this.isEditDialogVisible = true;
this.curRow = row
},
_c_delete(row, $index) {
this.curRow = row
this.$confirm('确认删除吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(res => {
this._i_delete(row, $index);
},res => {}
);
},
_c_confirm(isAdd){
isAdd? this._i_add():this._i_update()
},
_c_page_change(val) {
this.page.pageNo = val;
this._i_query();
},
}
}