在工作中经常会遇到需要数据以表格形式展示出来,但是一旦展示的数据过多,会导致table冗余,故通常需要自行封装table简化代码,提高复用性,如下:
<template>
<div class="table-content">
<el-table
v-bind="$attrs"
ref="eltable"
@selection-change="selectionChange"
@sort-change="sortChange"
>
<!-- 多选框 -->
<el-table-column
type="selection"
v-if="showSelect"
v-bind="selectionAttrs"
width="55"
align="center"
/>
<!-- 序号 -->
<el-table-column
v-if="showIndex"
type="index"
label="序号"
width="55"
align="center"
:index="indexMethod"
fixed
/>
<!-- 实际数据展示 -->
<el-table-column
v-for="(column, index) in tableTitles"
:key="index"
:label="column.tatle"
:prop="column.key"
:align="column.align || 'center'"
:header-align="column.headerAlign || 'center'"
:fixed="column.fixed ? column.fixed : false"
:sortable="column.sortable"
:width="column.width"
:formatter="column.formatter"
show-overflow-tooltip
>
<template slot-scope="scope">
<slot
v-if="column.render"
:name="column.render"
v-bind="{ row: scope.row, index, $index: scope.$index }"
/>
<span v-else-if="column.formatter">
{{
column.formatter(
scope.row,
column,
scope.row[column.key],
scope.$index
) | handleColumn
}}
</span>
<span v-else>{{
String(scope.row[column.key] || '') | handleColumn
}}</span>
</template>
<template slot="empty"
>d
<div>
暂无数据...
</div>
</template>
</el-table-column>
</el-table>
<!-- 分页部分 -->
<div v-if="pageFlag">
<div v-show="$attrs.data.length > 0" class="mypagination">
<div v-if="pageSlots" class="total fl">
共{{ pageInfo.total }}条记录 第{{ pageInfo.pageNum }}/{{
Math.ceil(pageInfo.total / pageInfo.pageSize)
}}页
</div>
<i v-else />
<el-pagination
prev-text="上一页"
next-text="下一页"
class="fr"
backgound
:layout="layout"
:pager-count="$attrs.pagerCount"
:page-sizes="[10, 20, 30, 40, 50]"
:page-size="pageInfo.pageSize"
:current-page="pageInfo.pageNum"
:total="pageInfo.total"
@size-change="$listeners['size-change']"
@current-change="$listeners['current-change']"
></el-pagination>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'CommonTable',
prop: {
showSelect: {
type: Boolean,
default: false
},
showIndex: {
type: Boolean,
default: true
},
indexCustomze: {
type: Boolean,
default: false
},
pageFlag: {
type: Boolean,
default: true
},
tableTitles: {
type: Array,
default: () => []
},
selectionAttrs: {
type: Object,
default: () => ({})
},
pageInfo: {
type: Object
},
layout: {
type: String,
default: 'sizes,prev,pager,next'
}
},
filters: {
handleColumn (val) {
if (val) return val
if (val + '' === '0') return '0'
if (!val) return '-'
}
},
data () {
return {
elTable: null,
historyData: [],
tmp: {},
sortCount: 0
}
},
mounted () {
this.elTable = this.$refs.elTable
},
methods: {
selectionChange (value) {
this.$emit('selection-change', value)
},
// 如表格存在切换,必须给当前表格绑定ref,咋切换数据时触发该方法
sortCountToZero () {
this.sortCount = 0
},
//排序
sortChange ({ column, prop, order }) {
// 判断当前是否为第一次点击,历史数据值存留一次
if (!this.sortCount && this.$attrs.data && this.$attrs.data.length > 0) {
this.historyData = [...this.$attrs.data]
this.tmp = this.$attrs.data[0]
this.sortCount++
}
this.$emit(
'sort-change',
{ column, prop, order },
this.historyData,
this.tmp
)
},
sort ({ column, prop, order }) {
this.$emit('sort', { column, prop, order })
},
indexMethod () {
if (this.indexCustomze) {
return indexed === 0 ? '' : index
} else {
return index + 1
}
}
}
}
</script>
<style lang="less" scoped>
.table-content {
background-color: #fff;
/deep/ .el-table_header {
tr {
font-weight: 700;
color: #262626;
th {
background-color: rgb(244, 245, 247);
}
}
}
.mypagination {
display: flex;
justify-content: space-between;
align-items: center;
height: 55px;
padding: 15px 0 10px;
.fl {
float: left;
font-size: 14px;
color: #999;
line-height: 14px;
}
.fr {
float: right;
}
/deep/ .el-pagination {
font-size: 14px;
font-weight: normal;
.btn-prev,
.btn-next {
padding: 0 16px;
background-color: #fff;
border: 1px solid #d9dce2;
border-radius: 4px;
height: 28px;
line-height: 28px;
}
.el-pager {
li {
min-width: 36px;
color: #262626;
height: 28px;
line-height: 28px;
border: 1px solid #d9dce2;
border-radius: 4px;
background-color: #fff !important;
&.active {
border: 1px solid #368fff;
color: #368fff;
}
}
}
}
}
}
/deep/.el-table_body-wrapper::-webkit-scrollbar-thumb {
background-color: #e6e6e6;
}
</style>
给表格中的数据进行排序处理:
// sort el-table回传表格排序方式
// historyData 历史表格数据
// tmp 表格首行数据(固定)
// self 指针 (this指向)
// table 表格数据名(默认'tableData')
function sortCallBack(tmp, self, table, callback) {
self[table].splice(0, 1)
self[table] = self[table].sort(callback)
self[table].unshift(tmp)
}
export function sortChange(sort, historyData, tmp, self, table = 'tableData') {
if (sort.order === 'descending') {
//降序
sortCallBack(tmp, self, table, (a, b) => {
return Number(b[sort.prop]) - Number(a[sort.prop])
})
} else if (sort.order === 'ascending') {
// 升序
sortCallBack(tmp, self, table, (a, b) => {
return Number(a[sort.prop]) - Number(b[sort.prop])
})
} else {
//还原 注意堆栈与引用变量是否采取深浅拷贝
self[table] = [ ...historyData ]
}
}
如何引用 如下:
<template>
<div id="app">
<!-- <router-view></router-view> -->
<!-- <img src="./assets/logo.png" alt="" /> -->
<Table
:showIndex="true"
:tableTitles="tableTitles"
:data="tableData"
:pageInfo="pageInfo"
:index-customze="true"
:pageFlag="true"
@current-change="handlePageChange"
@size-change="handlePageSizeChange"
@sort-change="sortChange"
>
<!-- 自定义可编辑或者可点击部分 -->
<template #areaName="{row,$index}">
<span v-if="$index === 0">{{ row.areaName }}</span>
<el-button v-else type="text" @click="clickFn(row)">{{
row.areaName
}}</el-button>
</template>
</Table>
</div>
</template>
<script>
import Table from './components/HelloWorld.vue'
import { sortChange } from './components/customzeSort'
export default {
name: 'App',
components: {
Table
},
data () {
return {
tableTitles: [
{
title: '地区',
key: 'areaName',
render: 'areaName',
fiexed: 'left',
width: '100px'
},
{
title: '机构数量',
key: 'organNum' //与接口获取的数据中字段一致
},
{
title: '教师数量',
key: 'teachers'
},
{
title: '学生数量',
key: 'students'
}
],
tableData: [
{ areaName: '北京', organNum: '123', teachers: '456', students: '789' }
],
pageInfo: {
pageNum: 1,
pageSize: 10,
total: 100
}
}
},
methods: {
sortChange (sort, historyData, tmp) {
sortChange(sort, historyData, tmp, this, 'tableData')
},
handlePageChange (pageNum) {
this.pageInfo.pageNum = pageNum
//修改分页参数 重新调取接口
},
handlePageSizeChange (pageSize) {
this.pageInfo.pageSize = pageSize
//修改分页参数 重新调取接口
},
clickFn (row) {
//点击表格内容 进行处理
}
}
}
</script>
|