基于element-ui实现的封装table,表格列通过render函数使用jsx渲染处理单个字段
效果如下
表格组件代码
<template>
<div class="table-management">
<el-table style="width: 100%"
:data="tblData"
v-loading="tbLoading"
v-bind="attrs"
element-loading-text="正在加载"
@selection-change="handleSelectionChange">
<el-table-column v-if="isSelect"
type="selection"
width="40">
</el-table-column>
<el-table-column v-for="(item, index) in column"
:key="index"
:type="item.type"
:index="item.index"
:column-key="item.columnKey"
:label="item.label"
:prop="item.prop"
:width="item.width"
:min-width="item.minWidth"
:fixed="item.fixed"
:header-align="item.headerAlign"
:align="item.align"
:show-overflow-tooltip="showOverflowTooltip">
<template slot="header">
<div v-if="item.tip">
<span>{{item.label}}</span>
<el-tooltip placement="right">
<div slot="content">
<div v-for="(items,index) in item.tipData"
:key="index">
<p>
{{items.msg}}
</p>
</div>
</div>
<i class="el-icon-question"></i>
</el-tooltip>
</div>
<p v-else>{{item.label}}</p>
</template>
<template slot-scope="scope">
<expand-dom v-if="item.render"
:render="item.render"
:row="scope.row"
:index="scope.$index"
:column="item"></expand-dom>
<span v-else>{{ scope.row[item.prop]||'-' }}</span>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination @size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pagination.curPage"
:page-sizes="pagination.pageSizes||defaultPagination.pageSizes"
:page-size="pagination.pageSize"
:layout="pagination.layout||defaultPagination.layout"
:total="pagination.total"
v-bind="pagination.attrs">
<span class="el-pagination__total">{{totalText}}</span>
</el-pagination>
</div>
</div>
</template>
<script>
export default {
props: {
tblData: { type: Array }, // 表格数据list
column: { type: Array }, // 表格展示的表头以及单元格字段
isSelect: { type: Boolean, default: false }, // 是否显示选中组件
tbLoading: { type: Boolean, default: false }, // 表格加载loading
pagination: {
type: Object,
require: true
},
// 表格的其他属性
attrs: Object
},
components: {
expandDom: {
functional: true,
props: {
row: Object,
render: Function,
index: Number,
column: {
type: Object,
default: null
}
},
render: (h, ctx) => {
const params = {
row: ctx.props.row,
index: ctx.props.index
}
if (ctx.props.column) params.column = ctx.props.column
return ctx.props.render(h, params)
}
}
},
data () {
return {
showOverflowTooltip: true,
defaultPagination: {
pageSizes: [10, 20, 50, 100],
layout: 'slot, prev, pager, next,sizes'
}
}
},
computed: {
totalText () {
const { total, curPage, pageSize } = this.pagination
const range = [total === 0 ? 0 : (curPage - 1) * pageSize + 1, curPage * pageSize > total ? total : curPage * pageSize]
return `共${total}条,当前页为 ${range[0]} - ${range[1]} 页`
}
},
methods: {
// 选中方法回调
handleSelectionChange (val) {
// 选中事件
this.$emit('handleSelectBtn', val)
},
handleButton (methods, row, index) {
// 按钮事件
this.$emit('handleButton', { methods: methods, row: row, index: index })
},
// 分页api(展示每页显示条数)
handleSizeChange (val) {
this.$emit('handleSizeChange', val)
},
// 分页点击api(获取当前页数据)
handleCurrentChange (val) {
this.$emit('handleCurrentChange', val)
}
},
mounted () { }
}
</script>
<style lang="scss" scope>
.table-management {
.pagination {
display: flex;
justify-content: flex-end;
margin: 10px 0;
}
}
.table-management .el-table-column--selection .cell {
text-overflow: unset;
}
.table-management {
.el-pagination.is-background .btn-next,
.el-pagination.is-background .btn-prev,
.el-pagination.is-background .el-pager li {
background: white;
}
.el-pagination.is-background .el-pager li:not(.disabled).active {
border: 1px solid #409eff;
color: #409eff;
background: white;
}
}
</style>
使用组件
<template>
<div>
<table-tem @handleSizeChange="handleSizeChange"
@handleCurrentChange="handleCurrentChange"
:tblData="tblData"
:attrs="attrs"
:column="column"
:isSelect="true"
:pagination="pagination"
@handleSelectBtn="handleSelectBtn">
</table-tem>
</div>
</template>
<script>
// 引入组件table
import tableTem from './table-it.vue'
export default {
components: {
tableTem
},
data () {
return {
attrs: {
border: true
// fit:false
},
tblData: [
{
imgUrl: 'https://img.yzcdn.cn/public_files/2017/10/24/2f9a36046449dafb8608e99990b3c205.jpeg',
timeList: [
{ startTime: '2022-1-2', endTime: '2020-4-3' }
],
type: 1,
StatusDesc: 'ssss',
createTime: '2020-3-4'
},
{
imgUrl: 'https://img.yzcdn.cn/public_files/2017/10/24/320454216bbe9e25c7651e1fa51b31fd.jpeg',
timeList: [
{ startTime: '2022-1-2', endTime: '2020-4-3' }
],
type: 2,
StatusDesc: 'ssss',
createTime: '2020-3-4'
}
], // 表格展示数据list,由接口获取
pagination: {
total: 67,
pageSize: 10,
curPage: 1,
attrs: {
// hideOnSinglePage: true,
background: true
}
},
selectList: [], // 储存列表选中的数据
column: [// 表格展示列,也就是表头字段
{
prop: 'imgUrl', // 表格渲染字段
label: 'logo', // 表头显示名字
headerAlign: 'center', // 表头样式-居中显示
align: 'center', // 单元格样式-居中显示
width: 120,
// 当前渲染字段api--列出显示img的api
render: (h, { row }) => <img src={row.imgUrl} width='80' height='80'></img>
},
{
prop: 'timeList',
label: '时间段',
headerAlign: 'center',
align: 'center',
render: this.renderTimeList
},
{
prop: 'type',
label: '类型',
headerAlign: 'center',
align: 'center',
render: this.renderType
},
{
prop: 'StatusDesc',
label: '状态',
headerAlign: 'center',
align: 'center',
tip: true, // 是否展示表头状态描述提示信息
tipData: [// 展示的提示信息数组
{ msg: '我是展示在状态表头里面的提示信息1' },
{ msg: '我是展示在状态表头里面的提示信息2' }
],
minWidth: 110
},
{
prop: 'createTime',
label: '创建时间',
headerAlign: 'center',
align: 'center',
minWidth: '90'
// render: this.renderCreateTime// 当前渲染字段api--(后端返回的是时间戳需要前端处理一下)
},
// 接下来就着重说一下表格的操作按钮(相同的字段前面都表述清楚了)
{
prop: 'operation',
label: '操作',
headerAlign: 'center',
align: 'center',
minWidth: '110',
// 该方法是针对操作一列的按钮的api
render: (h, { row }) => {
return <div>
<el-button type='danger' icon='el-icon-edit' style="cursor:pointer;" onClick={this.btnClick}>修改</el-button>
<el-button type='primary' style="cursor:pointer;" onClick={() => this.btnClick(row)}>删除</el-button>
</div>
}
}
]
}
},
methods: {
// 分页点击
handleCurrentChange (val) {
this.pagination.curPage = val
// 掉接口:获取表格数据接口
},
// 获取每页显示条数
handleSizeChange (val) {
this.pagination.curPage = 1
this.pagination.pageSize = val
// 掉接口:获取表格数据接口
},
// 列表选中回调api
handleSelectBtn (val) {
this.selectList = val
},
// 渲染时间数组
renderTimeList (h, { row: { timeList } }) {
const timeListArr = []
for (const i of timeList) {
timeListArr.push(i.startTime + '~' + i.endTime)
}
return <div>
{timeListArr.map((item, index) => <div>{item}</div>)}
</div>
},
// 状态渲染类
renderType (h, { row }) {
let statusStr = ''
if (row.type === 1) {
statusStr = '类型1'
} else if (row.type === 2) {
statusStr = '类型2'
} else if (row.type === 3) {
statusStr = '类型3'
} else {
statusStr = ''
}
return <span>{statusStr}</span>
},
// 下面是操作按钮一列
// 操作
btnClick (row) { console.log(row) }
}
}
</script>
实现中借鉴博主文章:elementui提取table表格封装组件,elementui提取table表格单列展示按钮的展示效果_管火火火的博客-CSDN博客_elementui table 封装