表格組件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
}
}
}
})
