TypeScript 基于ElementUI Tabel封装的表格组件合并方法
最近为公司做了一个 VUE 脚手架,采用的技术是 vue + TypeScript + element-ui 进行封装,这样以后公司就有了一个统一的规范,减少大家做不必要的重复工作,大家就可以直接拿来复用。目前整个一套 vue 脚手架基本封装完毕,但是还没有对外开源,只是内部使用,后期什么时候开源,我会第一时间在码云笔记上公布。因为我也是第一次使用 TypeScript 进行开发,一边学习一边使用,所以也是摸着石头过河,有很多不完美的地方还希望大家多多担待,好了废话不多说,直接上代码。
HTML 代码:
<template> <section class="usermanager"> <!-- 表格 --> <el-table :data="data" v-loading="loading" :element-loading-text="loadtext" :element-loading-spinner="loadspinner" :element-loading-background="loadbgcolor" :highlight-current-row="highlight" :border='border' :stripe='stripe' :span-method="this.mergeF ? this.mergeMethod : this.spanMethod" @sort-change="handleSort" row-key="name" style="width: 100%;"> <el-table-column :type="type" width="55"> </el-table-column> <template v-for="(item, index) in column"> <el-table-column :key="index" :label="item.label" :prop="item.prop" :show-overflow-tooltip="showtooltip" :reserve-selection='true' :sortable="sortable" ></el-table-column> </template> <slot></slot> </el-table> <!--页码--> <el-col :span="24" class="toolbar"> <el-pagination layout="total,jumper,prev, pager, next,sizes" :current-page="currentPage" :page-sizes="pagesizes" :page-size="pagesize" :total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange" style="float:right;"> </el-pagination> </el-col> </section> </template>
TS 部分:
<script lang="ts"> import { Component, Prop, Vue, Watch } from 'vue-property-decorator'; @Component({ name: 'XTable' }) export default class XTable extends Vue { // ======================props===================== // 加载 @Prop({type:Boolean,default:true}) loading!: boolean; // 加载内容 @Prop({type:String,default: '拼命加载中'}) loadtext!: string; // 加载图标类名 @Prop({type:String,default: 'el-icon-loading'}) loadspinner!: string; // 加载背景色值 @Prop({type:String,default: 'rgba(0, 0, 0, 0.8)'}) loadbgcolor!: string; // 边框显示 @Prop({type: Boolean, default:true}) border!: boolean; // 当内容过长被隐藏时显示 tooltip @Prop({type: Boolean,default:true}) showtooltip!: boolean; // 当前行高亮显示 @Prop({type:Boolean,default:true}) highlight!: boolean; // 对应列的类型 @Prop({ default: function () {return 'selection'}}) type!: 'selection' | 'index' | 'expand' // 表格数据 @Prop({ type: Array, default: function(){ return [] } }) data!: []; //表头数据 @Prop({ type: Array, default: function(){ return [] } }) column!: []; @Prop({ type: Array, default: function(){ return [] } }) merge!: []; // 每页显示个数选择器的选项设置 @Prop({ type: Array, default: function(){ return [] } }) pagesizes!: [] // 总条目数 @Prop(Number) total!: Number; // 每页显示条目个数,支持 .sync 修饰符 @Prop({type:Number, default:10}) pagesize!: Number; //当前页数,支持 .sync 修饰符 @Prop(Number) currentPage!: Number; // 全选单选 @Prop({ type: Array, default: function(){ return [] } }) sels!: []; // 是否可以排序 三个值可选:true, false, 'custom' @Prop({type:[Boolean,String],default:false}) sortable!: boolean; @Prop(Function) spanMethod?:Function; mergeLine: Object = {} mergeIndex: Object = {} get stripe(): boolean { return this.$attrs.stripe !== 'false' } // ======================created===================== created () { this.getMergeArr(this.data, this.merge) } // ======================mounted===================== mounted() { this.getMergeArr(this.data, this.merge) } // ======================methods===================== handleSizeChange (val: number){ this.$emit('handleSizeChange', val) } handleCurrentChange(currentPage: number) { this.$emit('handleCurrentChange', currentPage) } handleSort (column:any, prop:any, order:any) { this.data.sort((a, b) => { return Math.random() - 0.5 }) } // 合并单元格 getMergeArr (tableData: any, merge: any) { if (!merge) return this.mergeLine = {} this.mergeIndex = {} merge.forEach((item:any, k:any) => { tableData.forEach((data:any, i:any) => { if (i === 0) { (this as any).mergeIndex[item] = (this as any).mergeIndex[item] || []; (this as any).mergeIndex[item].push(1); (this as any).mergeLine[item] = 0; } else { if (data[item] === tableData[i - 1][item]) { (this as any).mergeIndex[item][(this as any).mergeLine[item]] += 1; (this as any).mergeIndex[item].push(0); } else { (this as any).mergeIndex[item].push(1); (this as any).mergeLine[item] = i; } } }) }) } mergeMethod (obj:{ row:any, column:any, rowIndex:any, columnIndex:any }) { const index = (this as any).merge.indexOf(obj.column.property) if (index > -1) { const _row = this.mergeIndex[this.merge[index]][obj.rowIndex] const _col = _row > 0 ? 1 : 0 return { rowspan: _row, colspan: _col } } } // ======================watch===================== @Watch('merge') mergeF (): void { this.getMergeArr(this.data, this.merge) } dataLength (): void { this.getMergeArr(this.data, this.merge) } } </script>
然后,我们在父组件内使用 x-table 进行调用,在上面配置 merge,merge 为一个包含需要合并的 column 中 prop 的数组,配置后会自动将值相同的项自动合并。
<ean-table :data="tableData.data" :column="tableData.column" :merge="['date','province']" > </ean-table>
最终效果:
以上知识提供参考,感谢阅读。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » TypeScript 基于ElementUI Tabel封装的表格组件合并方法
码云笔记 » TypeScript 基于ElementUI Tabel封装的表格组件合并方法