<!-- 子组件 -->
<!-- 子组件 -->
<template>
<div
class="y_table"
:class="{ y_table_moving: dragState.dragging }"
>
<el-table
:data="data"
resizable
stripe
size="small"
:show-summary="option.showSummary"
:height="option.height"
:max-height="conheight.height"
:border="option.border"
:style="{ width:option.width }"
:cell-class-name="cellClassName"
:header-cell-class-name="headerCellClassName"
:header-cell-style="{background:'#FAFAFA',}"
@sort-change="handleSort"
@selection-change="handleSelectionChange"
>
<el-table-column
v-if="showSelection"
align="center"
type="selection"
fixed="left"
width="55"
/>
<slot name="fixed"></slot>
<template v-for="(col, index) in tableHeader">
<!-- 操作列/自定义列 -->
<slot
v-if="col.slot"
:name="col.slot"
></slot>
<!-- 普通列 -->
<el-table-column
v-else
:key="index"
:sortable="col.sortable"
:prop="col.prop"
:fixed="col.fixed"
:label="col.label"
:width="col.width"
:min-width="col.minWidth"
:type="col.type"
:align="col.align"
:header-align="col.headerAlign"
:column-key="index.toString()"
:sort-method="col.sortMethod"
:show-overflow-tooltip="true"
/>
</template>
</el-table>
<el-pagination
v-if="option.hidePagibation"
class="pageination"
background
layout="total, sizes, prev, pager, next, jumper"
:page-sizes="
option.sizes && option.sizes.length > 0 ? option.sizes : [10,20,40, 60, 80,100,200]
"
:page-size="option.size"
:total="option.total"
:current-page.sync="currentPage"
@size-change="handlePageSize"
@current-change="handlePageCurrent"
/>
</div>
</template>
<script>
export default {
props: {
data: {
type: Array,
default: () => [],
},
showSelection: {
type: Boolean,
default: false,
},
header: {
type: Array,
default: () => [],
},
option: {
default: () => { },
type: Object,
},
cellClassName: {
type: String,
default: '',
},
headerCellClassName: {
type: String,
default: 'defaultBgc',
},
},
data() {
return {
tableHeader: this.header,
currentPage: 1,
dragState: {
start: -9, // 起始元素的 index
end: -9, // 移动鼠标时所覆盖的元素 index
dragging: false, // 是否正在拖动
direction: undefined, // 拖动方向
},
conheight: {
height: '',
},
};
},
watch: {
header(val, oldVal) {
this.tableHeader = val;
},
},
created() {
window.addEventListener('resize', this.getHeight);
this.getHeight();
},
methods: {
updateCurPage() {
this.currentPage = 1;
},
getHeight() {
this.conheight.height = `${window.innerHeight - 80}px`;
},
handlePageSize(e) {
this.$emit('handlePageSize', e);
},
handlePageCurrent(e) {
this.$emit('handlePageCurrent', e);
},
// 点击排序触发
handleSort(e) {
this.$emit('handleSort', e.order, e.prop);
},
// 多选的方法
handleSelectionChange(e) {
this.$emit('handleSelected', e);
},
},
};
</script>
<style lang="scss" scoped>
::v-deep .el-table {
border-top: 1px solid #dfe6ec !important;
}
.y_table {
width: 100%;
padding: 20px;
box-sizing: border-box;
height: calc(100% - 13rem);
.el-table .darg_start {
background-color: #f3f3f3;
}
.defaultBnc {
background-color: #f2f2f2;
}
.el-table th {
padding: 0;
.virtual {
position: fixed;
display: block;
width: 0;
height: 0;
margin-left: -10px;
background: none;
border: none;
}
&.darg_active_left {
.virtual {
border-left: 2px dotted #666;
z-index: 99;
}
}
&.darg_active_right {
.virtual {
border-right: 2px dotted #666;
z-index: 99;
}
}
}
.thead-cell {
padding: 0;
display: inline-flex;
flex-direction: column;
align-items: left;
cursor: pointer;
overflow: initial;
&:before {
content: "";
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
}
&.y_table_moving {
.el-table th .thead-cell {
cursor: move !important;
}
.el-table__fixed {
cursor: not-allowed;
}
}
}
</style>
父组件
<template>
<div>
<my-table
:header="tableHeader"
:data="tableData"
:show-selection="showSelection"
:option="tableOption"
@handlePageSize="handlePageSize"
@handlePageCurrent="handlePageCurrent"
@handleSort="handleSort"
@handleSelected="handleSelectionChanges"
>
<el-table-column
slot="lesseeName"
label="线索池名称"
width="200px"
>
<template slot-scope="{row}">
<el-button
type="text"
>
{{ row.tableDataName }}
</el-button>
</template>
</el-table-column>
<el-table-column
slot="set"
label="操作"
width="160px"
>
xxx
</el-table-column>
</my-table>
</div>
</template>
<script>
import myTable from './WTable';
export default defineComponent({
name: 'PriceUpsideDownTable',
components: {
myTable,
},
setup() {
// 表头
const tableHeader = [
{
type: 'index', // 从index开始的序号
},
{
prop: 'mainSkuId', // 绑定的对应prop,就是要渲染的数据
label: '主SKUID', // 绑定的对应label
align: 'center', // 对齐方式
headerAlign: 'left', // 表头对齐方式
minWidth: 130, // 表格最新宽度
sortable: true, // 是否可以排序
fixed: 'right', // 是否固定,值是left,right
}, {
prop: 'skuId',
label: 'SKUID',
align: 'center',
}, {
prop: 'skuName',
label: '商品名称',
minWidth: 300,
}, {
prop: 'specZsFactor',
label: '包规折算系数',
align: 'center',
minWidth: 160,
}, {
prop: 'creator',
label: '创建人',
}, {
prop: 'ctime',
label: '创建时间',
minWidth: 200,
}, {
slot: 'lesseeName',
},
];
// 数据
const tableData = [
{
tableDataName: '谢谢1',
skuName: 'xx1',
mainSkuId: 1,
skuId: 111,
creator: '魏广雨',
specZsFactor: '99',
ctime: '2022-09-20',
}, {
tableDataName: '谢谢2',
mainSkuId: 2,
skuId: 222,
skuName: 'xx2',
specZsFactor: '33',
creator: '魏广雨',
ctime: '2022-09-20',
}, {
tableDataName: '谢谢1',
skuName: 'xx1',
mainSkuId: 1,
skuId: 111,
creator: '魏广雨',
specZsFactor: '99',
ctime: '2022-09-20',
}, {
tableDataName: '谢谢2',
mainSkuId: 2,
skuId: 222,
skuName: 'xx2',
specZsFactor: '33',
creator: '魏广雨',
ctime: '2022-09-20',
}, {
tableDataName: '谢谢1',
skuName: 'xx1',
mainSkuId: 1,
skuId: 111,
creator: '魏广雨',
specZsFactor: '99',
ctime: '2022-09-20',
}, {
tableDataName: '谢谢2',
mainSkuId: 2,
skuId: 222,
skuName: 'xx2',
specZsFactor: '33',
creator: '魏广雨',
ctime: '2022-09-20',
}, {
tableDataName: '谢谢1',
skuName: 'xx1',
mainSkuId: 1,
skuId: 111,
creator: '魏广雨',
specZsFactor: '99',
ctime: '2022-09-20',
}, {
tableDataName: '谢谢2',
mainSkuId: 2,
skuId: 222,
skuName: 'xx2',
specZsFactor: '33',
creator: '魏广雨',
ctime: '2022-09-20',
}, {
tableDataName: '谢谢1',
skuName: 'xx1',
mainSkuId: 1,
skuId: 111,
creator: '魏广雨',
specZsFactor: '99',
ctime: '2022-09-20',
}, {
tableDataName: '谢谢2',
mainSkuId: 2,
skuId: 222,
skuName: 'xx2',
specZsFactor: '33',
creator: '魏广雨',
ctime: '2022-09-20',
}, {
tableDataName: '谢谢1',
skuName: 'xx1',
mainSkuId: 1,
skuId: 111,
creator: '魏广雨',
specZsFactor: '99',
ctime: '2022-09-20',
}, {
tableDataName: '谢谢2',
mainSkuId: 2,
skuId: 222,
skuName: 'xx2',
specZsFactor: '33',
creator: '魏广雨',
ctime: '2022-09-20',
}, {
tableDataName: '谢谢1',
skuName: 'xx1',
mainSkuId: 1,
skuId: 111,
creator: '魏广雨',
specZsFactor: '99',
ctime: '2022-09-20',
}, {
tableDataName: '谢谢2',
mainSkuId: 2,
skuId: 222,
skuName: 'xx2',
specZsFactor: '33',
creator: '魏广雨',
ctime: '2022-09-20',
}, {
tableDataName: '谢谢1',
skuName: 'xx1',
mainSkuId: 1,
skuId: 111,
creator: '魏广雨',
specZsFactor: '99',
ctime: '2022-09-20',
}, {
tableDataName: '谢谢2',
mainSkuId: 2,
skuId: 222,
skuName: 'xx2',
specZsFactor: '33',
creator: '魏广雨',
ctime: '2022-09-20',
}, {
tableDataName: '谢谢1',
skuName: 'xx1',
mainSkuId: 1,
skuId: 111,
creator: '魏广雨',
specZsFactor: '99',
ctime: '2022-09-20',
}, {
tableDataName: '谢谢2',
mainSkuId: 2,
skuId: 222,
skuName: 'xx2',
specZsFactor: '33',
creator: '魏广雨',
ctime: '2022-09-20',
},
];
// 是否需要多选
const showSelection = true;
// 控制分页的
const tableOption = {
border: true, // 是否需要表格边框
height: 'calc(100vh - 70px)', // 表格高度 我的除去表格其他的高度占70px,根据自己其他内容占的高度写
showSummary: false, // 是否展示合计行
hidePagibation: true, // 是否展示分页器
total: 100, // 总条数
size: 20, // 当前展示多少页
currentPage: 1, // 当前页
};
// 每页显示多少个发生变化
const handlePageSize = (v) => {
console.log(v);
};
// 当前页发生变化
const handlePageCurrent = (v) => {
console.log(v);
};
// 排序发生变化,哪个选项点击了排序
const handleSort = (ord) => {
console.log(ord);
};
// 多选
const handleSelectionChanges = (v) => {
console.log(v);
};
return {
tableHeader,
tableData,
showSelection,
tableOption,
handlePageSize,
handlePageCurrent,
handleSort,
handleSelectionChanges,
};
},
});
</script>
下面的和封装表格无关------------------------------
表格合并
spanMethod方法
// skuId/商品信息列
if (column.property === 'skuId') {
const cellValue = row[column.property];
if (cellValue) {
// 上一条数据
const prevRow = tableDatas[rowIndex - 1];
// 下一条数据
let nextRow = tableDatas[rowIndex + 1];
// 上一条等于这条数据,这条数据不显示
if (prevRow && prevRow[column.property] === cellValue) {
return { rowspan: 0, colspan: 0 };
} else { // 下一条数据等于这条数据,向下合并
let rowspan = 1;
while (nextRow && nextRow[column.property] === cellValue) {
rowspan += 1;
nextRow = tableDatas[rowspan + rowIndex];
}
return { rowspan, colspan: 1 };
}
}
}
// 也可以根据后端返回的数据格式自行处理,,仅个人看
// 获取表格数据
const responseProcessor = (response) => {
// 处理结构,返回新数组
const newList = response.skuList.reduce((tol, cur) => {
const { length } = cur.skuList;
const arr = cur.skuList.map((item, index) => ({ ...item, ...cur, rowSpan: index === 0 ? length : 0 }));
tol.push(...arr);
return tol;
}, []);
const res = {
data: newList || [],
total: response?.total,
};
return res;
};
const spanMethod = ({ row, column }) => {
// 需要合并的列
const arr = ['manageCityName', 'mainSkuId', 'poiCount', 'startTime'];
return [arr.includes(column.property) ? row.rowSpan : 1, 1];
};