当前位置: 首页 > 工具软件 > Object-table > 使用案例 >

Element UI 表格 el-table 二次封装

公西飞鸾
2023-12-01

Element UI 表格进行二次封装

Tips: 文章末尾有完整封装代码

一、继承 element 表格属性

需要将element提供的表格属性使用props传入组件中

props: {
	// 表头数据
	columns: {
	    type: Array
	},
	// 表格数据
	list: {
	    type: Array,
	    default() {
	        return []
	    }
	},
	// 加载动画
	loading: {
	    type: Boolean,
	    default: false
	},
	// 表格宽度
	width: [String, Number],
	// 表格高度
	height: [String, Number],
	// 表格最大高度
	maxHeight: [String, Number],
	// 单元格的 style 样式 Function({row, column, rowIndex, columnIndex})/String
	cellStyle: {
	    type: Object,
	    default() {
	        return {
	            borderRight: '1px solid white'
	        }
	    }
	},
	// 显示表头
	showHeader: {
	    type: Boolean,
	    default: true
	},
	// 列的宽度是否自撑开
	fit: {
	    type: Boolean,
	    default: true
	},
	// Table 的尺寸 medium / small / mini
	size: {
	    type: String
	},
	tableRowClassName: {
	    type: [Function, Boolean],
	    default: false
	}
}

二、配置 element 表格的表头

  1. 使用 props 传入的表头数据遍历得到表格的表头。
<el-table-column
    v-for="item in columns" :key="item.prop"
    :prop="item.prop"
    :label="item.label"
    :align="item.align || 'left'"
    :header-align="item.headerAlign || 'left'"
    :show-overflow-tooltip="item.tooltip || false"
    :min-width="item.minWidth"
    :width="item.width"
    :fixed="item.fixed"
    :class-name="item.columnClass"
    :label-class-name="item.labelClassName"
></el-table-column>
<!-- or -->
<el-table-column v-for="item in columns" :key="item.prop" v-bind="item"></el-table-column>
  1. 有些列的数据需要自定义内容,例如:操作列、不同样式的数据展示等。

需要自定义内容的列可以使用 <slot></slot> 传入自定义内容;这里就不能直接在 <el-table-column></el-table-column> 上使用 v-for 来遍历了,需要使用 <template></template> 来进行 v-for 的循环遍历,此时需要注意的是 v-for 需要定义一个 v-bind:key 但是不能直接将 key 赋给 <template ></template > 但是可以将 key 赋给其他组件 例如 <el-table-column :key="index"></el-table-column>

<template v-for="item in columns">
    <!-- 操作列/自定义列 -->
    <slot v-if="item.slot" :name="item.slot"></slot>
    <el-table-column
        v-else
        :key="item.prop"
        :prop="item.prop"
        :label="item.label"
        :align="item.align || 'left'"
        :header-align="item.headerAlign || 'left'"
        :show-overflow-tooltip="item.tooltip || false"
        :min-width="item.minWidth"
        :width="item.width"
        :fixed="item.fixed"
        :class-name="item.columnClass"
        :label-class-name="item.labelClassName"
    ></el-table-column>
    <!-- or
	<el-table-column v-for="item in columns" :key="item.prop" v-bind="item"></el-table-column>
	-->
</template>

三、element 表格事件

  1. Table Events 如果需要使用一些表格返回的事件,可以使用 this.$emit() 传递给父组件

例如@cell-click 当某个单元格被点击时会触发该事件 row, column, cell, event

// @cell-click="cellClick"
methods: {
	cellClick(row, column, cell, event) {
		this.$emit('cell-click', {row, column, cell, event})
	}
}
  1. Table Methods 如果需要使用一些表格的方法,可以在父组件使用 this.$refs['父组件中子组件的ref'].$refs['子组件table的ref'].方法名 调用

例如clearSort() 用于清空排序条件,数据会恢复成未排序的状态

//父组件
<template>
	<p-table ref="package-table" :columns="columns" :list="list"></p-table>
</template>

<script>
	export default {
		methods: {
			clearSort() {
				this.$refs['package-table'].$refs.table.clearSort()
			}
		}
	}
</script>

// 子组件
<template>
    <el-table ref="table"></el-table>
</template>

至此,对 element 表格的二次封装就已经大功告成了!

完整代码

<template>
    <el-table
        ref="table"
        :data="list"
        :width="width"
        :height="height"
        :maxHeight="maxHeight"
        :row-class-name="tableRowClassName || defaultClassName"
        :cell-style="cellStyle"
        :show-header="showHeader"
        :fit="fit"
        :size="size"
        v-loading="loading"
    >
        <template v-for="item in columns">
            <!-- 操作列/自定义列 -->
            <slot v-if="item.slot" :name="item.slot"></slot>
            <el-table-column v-for="item in columns" :key="item.prop" v-bind="item" />
            <!--
				<el-table-column
	                v-else
	                :key="item.prop"
	                :prop="item.prop"
	                :label="item.label"
	                :align="item.align || 'left'"
	                :header-align="item.headerAlign || 'left'"
	                :show-overflow-tooltip="item.tooltip || false"
	                :min-width="item.minWidth"
	                :width="item.width"
	                :fixed="item.fixed"
	                :class-name="item.columnClass"
	                :label-class-name="item.labelClassName"
	            />
			-->
        </template>
    </el-table>
</template>

<script>
export default {
    name: 'package-table',
    props: {
    	// 表头数据
        columns: {
            type: Array
        },
        // 表格数据
        list: {
            type: Array,
            default() {
                return []
            }
        },
        // 加载动画
        loading: {
            type: Boolean,
            default: false
        },
        // 表格宽度
        width: [String, Number],
        // 表格高度
        height: [String, Number],
        // 表格最大高度
        maxHeight: [String, Number],
        // 单元格的 style 样式 Function({row, column, rowIndex, columnIndex})/String
        cellStyle: {
            type: Object,
            default() {
                return {
                    borderRight: '1px solid white'
                }
            }
        },
        // 显示表头
        showHeader: {
            type: Boolean,
            default: true
        },
        // 列的宽度是否自撑开
        fit: {
            type: Boolean,
            default: true
        },
        // Table 的尺寸 medium / small / mini
        size: {
            type: String
        },
        tableRowClassName: {
            type: [Function, Boolean],
            default: false
        }
    },
    data() {
        return {
            
        }
    },
    created() {},
    methods: {
        defaultClassName({row, rowIndex}) {
            if (rowIndex%2 == 0) {
                return 'stripe-row';
            }
            return '';
        }
    }
}
</script>

<style>
    .el-table .stripe-row {
        background: #EFEFEF;
    }
</style>

Ending…
ding…
ng…

.

 类似资料: