基於ElementUi封裝table組件——包含表頭工具欄、多級表頭、合並行、分頁


表格組件WTable.vue

<template>
    <div class="wTable">
        <!-- 頭部工具欄 -->
        <div v-if="tools && tools.length>0 && tools[0].label" class="toolBar">
            <template v-for="(tool, key) in tools">
                <!-- 具名插槽 -->
                <slot v-if="tool.slot" :name="tool.slot" />
                <el-button
                    v-else
                    :key="key"
                    :type="tool.type"
                    :size="tool.size"
                    :plain="tool.plain"
                    :round="tool.round"
                    :circle="tool.circle"
                    :icon="tool.icon"
                    :style="tool.style"
                    :disabled="tool.disabled"
                    @click.native.prevent="tool.method()"
                >
                    {{ tool.label }}
                </el-button>
            </template>
        </div>
        <!-- 表格 -->
        <el-table
            id="wTable"
            ref="wTable"
            v-loading.wTable="woptions.loading"
            v-tableDrag 
            :data="data"
            :height="tHeight"
            :stripe="woptions.stripe"
            :border="woptions.border"
            :fit="woptions.fit"
            :span-method="spanMethod"
            :row-key="rowKey"
            @selection-change="handleSelectionChange"
        >
            <!-- 多選框 -->
            <el-table-column v-if="woptions.mutiSelect" :reserve-selection="true" type="selection" :selectable="woptions.checkSelect" style="width: 55px;" align="center" />
            <!-- 序號 -->
            <el-table-column v-if="woptions.index" label="序號" type="index" style="width: 55px;" align="center" />
            <!-- 數據列 -->
            <template v-for="(column, index) of columns">
                <!-- 如過有嵌套,遞歸多級表頭 -->
                <template v-if="column.children && column.children.length > 0">
                    <WColumn :key="index" :column="column" />
                </template>
                <!-- 沒有正常顯示 -->
                <template v-else>
                    <!-- 具名插槽 -->
                    <slot v-if="column.slot" :name="column.slot" />
                    <el-table-column
                        v-else-if="!column.isHide"
                        v-slot="scope"
                        :key="index"
                        :prop="column.prop"
                        :label="column.label"
                        :type="column.type"
                        :min-width="column.minWidth"
                        :width="column.width"
                        :align="column.align"
                        :fixed="column.fixed"
                        :show-overflow-tooltip="column.tooltip"
                        :class-name="column.class"
                        :sortable="column.sort"
                    >
                        <!-- 是否需要特殊處理 -->
                        <template v-if="column.formatter">
                            <span v-html="column.formatter(scope.row, column)" />
                        </template>
                        <template v-else>
                            <!-- 正常顯示 -->
                            <span>{{ scope.row[column.prop] }}</span>
                        </template>
                    </el-table-column>
                </template>
            </template>
        </el-table>
        <!-- 分頁 -->
        <div v-if="isPagination" class="pagination">
            <el-pagination
                background
                :current-page="wpagination.currentPage"
                :page-sizes="wpagination.pageArr"
                :page-size="wpagination.pagesize"
                layout="total, sizes, prev, pager, next, jumper"
                :total="total"
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
            />
        </div>
    </div>
</template>

<script>
/**
 * 使用方法:
 * 通用的可參考 views/businessManage/businessList
 * 多級表頭可參考 views/dingdang/privacyCallInfo
 * 合並行可參考 views/codeManage/routeTest
 */
import WColumn from './WColumn'
export default {
    name: 'WTable',
    components: { WColumn },
    props: {
        // 頭部按鈕組
        tools: {
            type: Array,
            default() {
                return [
                    {method() {}}
                ]
            }
        },
        // 數據
        data: {
            type: Array,
            requre: true,
            default() {
                return []
            }
        },
        // 合並行
        spanMethod: Function,
        // 多選回顯key
        rowKey: {
            type: String,
            default: 'id'
        },
        /**
         * 表格默認配置
         * height: 表格高度
         * stripe: 是否為斑馬紋 table
         * border: 是否帶有縱向邊框
         * fit: 列的寬度是否自撐開
         * mutiSelect: 是否開啟多選
         * loading: 添加loading
         */
        options: {
            type: Object,
            default() {
                return {
                    stripe: true,
                    border: false,
                    fit: true,
                    mutiSelect: false,
                    loading: false,
                    index: true
                }
            }
        },
        // 表格高度
        tHeight: {
            type: Number,
            default: 200
        },
        /**
         * 列集合
         * prop: 列字段
         * label: 列名稱
         * align: 文本顯示位置
         * width: 列固定寬度,例:200
         * minWidth: 自適應寬度 例: 200 或 20%
         * type: 類型
         * formatter: 特殊處理
         * slot: 特殊列名稱
         * isHide: 是否隱藏列,用於動態展示列
         * tooltip: 超出是否...
         * class: 列的class
         * sort: 是否排序
         */
        columns: {
            type: Array,
            default() {
                return []
            },
            require: true
        },
        // 數據總數
        total: {
            type: Number,
            default: 0
        },
        // 是否顯示分頁
        isPagination: {
            type: Boolean,
            default: true
        },
        /**
         * 分頁參數
         * pagesize:每頁顯示的條數
         * currentPage:當前頁碼
         * pageArr: 顯示多少條集合
         * background: 是否要背景
         */
        pagination: {
            type: Object,
            default() {
                return {
                    pagesize: 10,
                    background: true,
                    currentPage: 1,
                    pageArr: [10, 20, 50, 100]
                }
            }
        }
    },
    data() {
        return {
            // 默認的表格配置
            woptions: {
                stripe: true,
                border: false,
                fit: true,
                mutiSelect: false,
                loading: false,
                index: true,
                checkSelect() {
                    return true
                }
            },
            // 默認的分頁配置
            wpagination: {
                pagesize: 10,
                background: true,
                currentPage: 1,
                pageArr: [10, 20, 50, 100]
            }
        }
    },
    created() {
        // 擴展配置,目的是引用組件不用把配置全寫一遍
        this.woptions = Object.assign({}, this.woptions, this.options)
        this.wpagination = Object.assign({}, this.wpagination, this.pagination)
    },
    methods: {
        // 表格多選
        handleSelectionChange(val) {
            this.$emit('handleSelectionChange', val)
        },
        // 選擇每頁展示的條數
        handleSizeChange(size) {
            this.$emit('handleSizeChange', size)
        },
        // 點擊第幾頁
        handleCurrentChange(currentPage) {
            this.$emit('handleCurrentChange', currentPage)
        }
    }
}
</script>

<style lang="scss" scoped>
.wTable {
    box-shadow: 0 0 10px #eee;
    .toolBar {
        padding: 10px;
        overflow: hidden;
    }
    .pagination {
        padding: 30px 0;
        text-align: center;
    }
    #table {
        width: 100%;
    }
}
</style>

多級表頭遞歸子組件WColumn.vue

<template>
    <el-table-column
        v-if="!column.isHide"
        :prop="column.prop"
        :label="column.label"
        :type="column.type"
        :min-width="column.minWidth"
        :width="column.width"
        :align="column.align"
        :fixed="column.fixed"
        :show-overflow-tooltip="column.tooltip"
        :class-name="column.class"
        :sortable="column.sort"
    >
        <!-- 數據列 -->
        <template v-for="(item, key) of column.children">
            <template v-if="item.children && item.children.length > 0">
                <WColumn :key="key" :column="item" />
            </template>
            <template v-else>
                <!-- 具名插槽 -->
                <slot v-if="item.slot" :name="item.slot" />
                <el-table-column
                    v-else-if="!item.isHide"
                    v-slot="scope"
                    :key="key"
                    :prop="item.prop"
                    :label="item.label"
                    :type="item.type"
                    :min-width="item.minWidth"
                    :width="item.width"
                    :align="item.align"
                    :fixed="item.fixed"
                    :show-overflow-tooltip="item.tooltip"
                    :class-name="item.class"
                    :sortable="item.sort"
                >
                    <!-- 是否需要特殊處理 -->
                    <template v-if="item.formatter">
                        <span v-html="item.formatter(scope.row, item)" />
                    </template>
                    <template v-else>
                        <!-- 正常顯示 -->
                        <span>{{ scope.row[item.prop] }}</span>
                    </template>
                </el-table-column>
            </template>
        </template>
    </el-table-column>
</template>

<script>
export default {
    name: 'WColumn',
    props: {
        column: {
            type: Object,
            default() {
                return {}
            }
        }
    }
}
</script>

自定義點擊表格橫向滾動指令v-tableDrag

main.js將directices.js引入即可

import Vue from 'vue'

Vue.directive('tableDrag', {
    inserted: function(el) {
        el = el.getElementsByClassName('el-table__body-wrapper')[0]
        el.style.cursor = 'grab'
        el.onmousedown = function() {
            let gapX = event.clientX
            let startX = el.scrollLeft
            document.onmousemove = function(e) {
                let x = e.clientX - gapX
                el.scrollLeft = startX - x
                return false
            }
            document.onmouseup = function() {
                document.onmousemove = null
                document.onmouseup = null
            }
        }
    }
})


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM