基于element 封装一个简单的表格组件

<!--  子组件   -->
<!--  子组件   -->
<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];
    };

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值