elementui 表格二次封装

📅 2026/7/11 14:21:45
elementui 表格二次封装
学习记录仅供参考Vue.component(c-table, { props: { data: Object, ref_c:String, key:Number, row_class:Function, row_style:Function, header_style: { type:Function, default:function () { return {color:#10416c} // return {} } }, default_sort: { type:Function, default:function () { return {} } }, span_method: Function, expandKeys:{ type: Array, // 对象或数组默认值必须从一个工厂函数获取 default: function () { return [] } }, }, watch: { data: { handler(newVal) { this.init(newVal); }, immediate: true, deep: true, }, }, computed: { filterTableData() { if (this.table.pagination) { if (this.table.sidePagination client) {//前台分页 this.table.total this.table.tableData.length; return this.table.tableData.slice((this.table.currentPage - 1) * this.table.pageSize, this.table.currentPage * this.table.pageSize); } else {//后台分页 return this.table.tableData; } }else { return this.table.tableData; } }, start(){ return (this.table.currentPage - 1) * this.table.pageSize 1 }, end(){ let page Math.ceil(this.table.total / this.table.pageSize) if (this.table.currentPage page) { return this.table.total } else { return this.table.currentPage * this.table.pageSize } }, }, data() { return { templateSelection: , //当前选择行的id (单选) table: { showHeader: true, //是否显示表头 size: mini, //表格大小类型 medium / small / mini heightMinus: 0, //高度差值 height: 500, //高度 isStripe: false, //是否斑马纹 isBorder: true, //是否边框 fit: true, //列的宽度是否自动撑开 isRadio: false, //是否单选 radioId: id, //单选的value值 rowKeys:id,//行的唯一标示 expandAll:false,//树形表时是否默认展开 expandRow:false,//是否开启展开行 highlightCurrentRow:false,//是否高亮当前行 columns: [], //列数据 tableData: [], //表数据 // isRowBgc:true, //是否开启根据行某个属性更改背景 // rowClassName: null, //行背景及其根据哪一个属性进行判断是否背景 pagination: true, sidePagination: client,//server currentPage: 1, total: 0, pageSizes: [10, 20, 30, 50, 100], pageSize: 50, layout: slot,total,sizes,-, prev, pager, next, }, } }, mounted(){ this.$nextTick(function () { if (this.table.heightMinus) { this.table.height window.innerHeight - this.table.heightMinus; } }) window.addEventListener(resize, () { if (this.table.heightMinus) { this.table.height window.innerHeight - this.table.heightMinus; } }) }, methods: { //将父组件的配置覆盖默认值 async init(val) { for (let key in val) { if (Object.keys(this.table).includes(key)) { this.table[key] val[key]; } } }, //分页序号累加 count(index) { return (this.table.currentPage - 1) * this.table.pageSize index 1 }, //单选 singleElection(row) { this.$emit(radio-change, row); }, //多选(切换就触发) handleSelectionChange(val) { this.$emit(select-change, val); }, //多选 handleSelect(val, row) { this.$emit(select, val, row); }, //全选 selectAll(val) { this.$emit(select-all, val); }, //单元格点击事件 handleCellClick(row, column, cell, event) { // console.log(row, column, cell, event) this.$emit(cell-click, row, column, cell, event); }, //行点击事件 handleRowClick(row, column, event) { // console.log(row, column, cell, event) this.$emit(row-click, row, column, event); }, //点击当前行状态改变更换背景颜色后配合业务事件 handleTableCurrentChange(val) { this.$emit(row-change,val); }, //过滤 handleFilterChange(val) { this.$emit(filter-change,val); }, //点击展开行触发 handleExpandChange(row, expandedRows) { this.$emit(expand-change,row, expandedRows); }, //自定义排序规则 handleSortChange({column, prop, order}) { this.$emit(sort-change,column, prop, order); }, //分页 handleSizeChange(val) { if (this.table.sidePagination client) {//前台分页 this.table.pageSize val }else { this.$emit(size_change, val); } }, handleCurrentChange(val) { if (this.table.sidePagination client) {//前台分页 this.table.currentPage val }else { this.$emit(current_change, val); } }, }, template: div stylewidth:100%;display: flex;flex-direction: column; :style{height: table.heightpx} el-table :refref_c :keykey :show-headertable.showHeader :sizetable.size :stripetable.isStripe :datafilterTableData :bordertable.isBorder :heighttable.pagination?table.height-50:table.height :max-heighttable.maxHeight :row-keytable.rowKeys :tree-props{children: children} :default-expand-alltable.expandAll :row-class-namerow_class :row-stylerow_style :header-cell-styleheader_style :highlight-current-rowtable.highlightCurrentRow :expand-row-keysexpandKeys :span-methodspan_method :default-sort default_sort current-changehandleTableCurrentChange selection-changehandleSelectionChange selecthandleSelect select-allselectAll cell-clickhandleCellClick row-clickhandleRowClick filter-changehandleFilterChange expand-changehandleExpandChange sort-changehandleSortChange !--单选-- el-table-column v-iftable.isRadio aligncenter width55 label template slot-scopescope el-radio inputsingleElection(scope.row) classradio v-modeltemplateSelection :labelscope.row[table.radioId] stylespan/span/el-radio /template /el-table-column !--展开行-- el-table-column v-iftable.expandRow typeexpand width45 template slot-scopeprops slot nameexpand :rowprops.row :indexprops.$index/slot /template /el-table-column !--建立表头-- template v-for(item, index) in table.columns el-table-column v-ifitem.slot :keyitem.key||index :typeitem.type :propitem.prop :labelitem.label :widthitem.width :min-widthitem.minWidth :alignitem.align :header-alignitem.headerAlign :sortableitem.sortable :show-overflow-tooltipitem.overFlow :filtersitem.filterArray :filter-methoditem.filterHandler template v-ifitem.headerSlot slotheader slot-scopescope slot :nameitem.header :rowscope.row :indexscope.$index/slot /template template slot-scopescope slot :nameitem.slot_name :rowscope.row :indexscope.$index/slot /template /el-table-column el-table-column v-else :keyitem.key||index :indexcount :fixeditem.isFixed v-showitem.hide :typeitem.type :propitem.prop :labelitem.label :widthitem.width :min-widthitem.minWidth :alignitem.align :header-alignitem.headerAlign :sortableitem.sortable :sort-methoditem.sortMethod :formatteritem.formatter :reserve-selectiontrue :show-overflow-tooltipitem.overFlow :filtersitem.filterArray :filter-methoditem.filterHandler :column-keyitem.colKey :filter-multipleitem.filterMultiple :filtered-valueitem.filterValue template v-ifitem.headerSlot slotheader slot-scopescope slot :nameitem.header :rowscope.row :indexscope.$index/slot /template /el-table-column /template template slotempty slot nameempty / /template /el-table !-- 分页组件 -- !-- size-change每页条数 pageSize 改变时会触发 -- !-- current-change当前页 currentPage 改变时会触发 -- !-- page-size 每页显示条目个数支持 .sync 修饰符 -- !-- page-sizes 每页显示个数选择器的选项设置 -- el-pagination background v-iftable.pagination table.total0 size-changehandleSizeChange current-changehandleCurrentChange :current-page.synctable.currentPage :page-sizetable.pageSize :total.synctable.total :page-sizestable.pageSizes :layouttable.layout stylepadding-top:10px;height: 50px span classpageInfo stylemargin-right: 10px;font-weight: 400;color: #606266; 当前显示第 {{ start }} 至第 {{ end }} 条内容 , /span /el-pagination /div });使用c-table refmultipleTable :ref_csonTable :datatable v-loadingloading selecthandleSelect select-allselectAll size_changesizeChange//后端分页才写 current_changecurrentChange//后端分页才写 template v-slot:controls_slotscope el-button typeprimary clickedit(scope.row)编辑/el-button el-button typedanger clickdelete(scope.row)删除/el-button /template /c-tableloading: true, table: { heightMinus: 60, rowKeys:chartId,//行唯一标识默认为id sidePagination: server,//后台分页 currentPage: 1,//后台分页 total: 0,//后台分页 pageSize: 50,//后台分页 tableData: [], // 行数据 columns: [ {type: selection, label: , align: center},//复选框 {prop: name, label: 名称, minWidth: 250,overFlow: true}, {slot: true, slot_name: controls_slot, label: 操作, minWidth: 150, align: center}, ] sizeChange(val) { this.table.pageSize val }, currentChange(value) { this.table.currentPage value },