1、src\components\Table\index.vue
<!--
* @Description: render函数封装table
* @Author: 刘龙蛟
* @Email: 153284575@qq.com
* @Date: 2019-10-24 09:45:04
* @LastEditTime: 2021-03-18 09:58:15
* @LastEditors: Dragon
-->
<template>
<div class="table-wrapper">
<el-table
v-loading="loading"
style="width: 100%;"
:data="data"
:border="isBorder"
:header-cell-style="headerRowStyle"
:row-class-name="tableRowClassName"
:default-sort="defaultSort"
v-bind="$attrs"
v-on="$listeners"
@current-change="handleCurrentChange"
@selection-change="handleSelectionChange"
@select="handleSelect"
@select-all="handleSelectAll"
@sort-change="handleSortChange"
>
<slot name="selection" /> <!--此处可以加自定义项-->
<slot name="index" />
<el-table-column
v-for="(col, index) in rowHeader"
:key="index"
:prop="col.prop"
:label="col.label"
:min-width="col.minWidth"
:width="col.width"
:render-header="col.renderHeader"
:align="col.textCenter?col.textCenter:'center'"
:fixed="col.fixed"
:sortable="col.sortable"
>
<template slot-scope="scope">
<user-slot
v-if="col.render"
:render="col.render"
:row="scope.row"
:index="index"
:column="col"
/>
<!--对结果进行处理 配置了html标签,就是展示标签-->
<user-slot
v-if="handleValue.hasOwnProperty(col.prop)&&handleValue[col.prop].callback(scope.row[col.prop]).html"
:render="handleValue[col.prop].callback(scope.row[col.prop]).render"
:row="scope.row"
:index="index"
:column="col"
/>
<!--没有配置标签,就展示回调函数处理后的结果-->
<span
v-else-if="handleValue.hasOwnProperty(col.prop)&&!handleValue[col.prop].callback(scope.row[col.prop]).html"
>{{ handleValue[col.prop].callback(scope.row[col.prop]).value }}</span>
<!--没有对结果进行处理就展示纯文本-->
<span v-if="!col.render">{{ scope.row[col.prop] }}</span>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import userSlot from './userSlot.js'
export default {
components: {
'user-slot': userSlot,
},
props: {
handleValue: {
// 处理render里标签数据
type: Object,
default: () => {
return {}
},
},
data: {
// 表格数据
type: Array,
default: () => {
return []
},
},
rowHeader: {
// 表头展示信息
type: Array,
default: () => {
return []
},
},
isBorder: Boolean, // 显示边框
defaultSort: {
type: Object,
default: () => {},
}, // 排序
height: {
type: String,
default: '100%',
}, // 排序
loading: {
type: Boolean,
default: false,
},
},
data() {
return {
headerRowStyle: {
'font-weight': '600',
'font-size': '14px',
color: '#333333',
background: '#F9F9F9',
},
}
},
methods: {
// 隔行变色
tableRowClassName({ row, rowIndex }) {
if (rowIndex % 2 === 1) {
return 'double-row'
}
return ''
},
// 当表格的当前行发生变化的时候会触发该事件
handleCurrentChange(value) {
this.$emit('currentChange', value)
},
// 当选择项发生变化时会触发该事件
handleSelectionChange(value) {
this.$emit('selectionChange', value)
},
// 当用户手动勾选数据行的 Checkbox 时触发的事件
handleSelect(selection, row) {
this.$emit('select', selection, row)
},
// 当用户手动勾选全选 Checkbox 时触发的事件
handleSelectAll(selection) {
this.$emit('selectAll', selection)
},
// 排序
handleSortChange(column) {
this.$emit('handleSortChange', column)
},
},
}
</script>
<style lang="scss">
.table-wrapper {
/* margin-top: 20px; */
.el-table .double-row {
background: #f9f9f9;
}
.el-table th > .cell {
font-weight: 600;
}
.el-table .cell {
overflow: visible;
}
.el-button--text {
padding: 0;
margin: 0 5px;
}
.caret-wrapper {
height: 22px;
.sort-caret.descending {
bottom: 0px;
}
.sort-caret.ascending {
top: 0px;
}
}
.classhidden {
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: block;
// color: #409EFF;
cursor: pointer;
margin: 0;
}
.el-table--border::after,
.el-table--group::after,
.el-table::before {
z-index: 0;
}
}
</style>
2、src\components\Table\userSlot.js
const userSlot = {
functional: true,
props: {
row: Object,
render: Function,
index: Number,
column: {
type: Object,
default: null
}
},
render: (h, context) => {
const params = {
row: context.props.row,
index: context.props.index
}
if (context.props.column) params.column = context.props.column
return context.props.render(h, params)
}
}
export default userSlot
3、调用
<TableBox
:loading="listLoading"
element-loading-text="Loading"
element-loading-spinner="el-icon-loading"
:data="dataList"
:row-header="rowHeader"
:is-border="true"
>
<!-- (当前页 - 1) * 当前显示数据条数 + 当前行数据的索引 + 1 -->
<el-table-column type="index" slot="index" align="center" label="序号" width="60">
<template
slot-scope="scope"
>{{ (listQuery.data.page - 1) * listQuery.data.pagesize + scope.$index + 1 }}</template>
</el-table-column>
</TableBox>
完整代码
<template>
<div class="app-container">
<TableBox
:loading="listLoading"
element-loading-text="Loading"
element-loading-spinner="el-icon-loading"
:data="dataList"
:row-header="rowHeader"
:is-border="true"
>
<!-- (当前页 - 1) * 当前显示数据条数 + 当前行数据的索引 + 1 -->
<el-table-column type="index" slot="index" align="center" label="序号" width="60">
<template
slot-scope="scope"
>{{ (listQuery.data.page - 1) * listQuery.data.pagesize + scope.$index + 1 }}</template>
</el-table-column>
</TableBox>
<!-- 分页 -->
<pagination
:total="total"
:layout="'total, prev, pager, next, jumper'"
:page.sync="listQuery.data.page"
:limit.sync="listQuery.data.pagesize"
@pagination="refresh"
/>
</div>
</template>
<script>
import TableBox from '@/components/Table'
import Pagination from '@/components/Pagination'
import { mixinTable } from './mixin'
export default {
mixins: [mixinTable],
components: {
TableBox,
Pagination,
},
data() {
return {
listLoading: true,
}
},
created() {
this.refresh()
},
}
</script>
分页请看pagination
4、rowHeader添加表格所需要展示的字段src\views\table\mixin.js
rowHeader: [
{
prop: 'title',
label: '标题',
render: (h, params) => {
return (
<div class='ellipsis-text' style='color: red'>
{params.row.title}
</div>
)
}
}
]
完整代码
import { getList } from '@/api/table'
export const mixinTable = {
data() {
return {
listQuery: {
data: {
page: 1,
pagesize: 5,
},
},
dataList: [], // 表格数据
total: 0, // 总条数
rowHeader: [
{
prop: 'title',
label: '标题',
render: (h, params) => {
return (
<div class='ellipsis-text' style='color: red'>
{params.row.title}
</div>
)
}
},
{
prop: 'author',
label: '权限',
render: (h, params) => {
return (
<div>{params.row.author}</div>
)
}
},
{
prop: 'pageviews',
label: 'Pageviews',
width: 150,
render: (h, params) => {
return (
<div>
{params.row.pageviews}
</div>
)
}
},
{
prop: 'status',
label: '状态',
width: 200,
render: (h, params) => {
return (
<div>
{
params.row.status === 'published' && <el-tag type="success">{params.row.status}</el-tag> ||
params.row.status === 'draft' && <el-tag type="gray">{params.row.status}</el-tag> ||
params.row.status === 'deleted' && <el-tag type="danger">{params.row.status}</el-tag>
}
</div>
)
}
},
{
prop: 'display_time',
label: 'Display_time',
render: (h, params) => {
return (
<div>
<i class="el-icon-time" />
{
params.row.display_time
}
</div>
)
}
},
// 添加操作按钮
{
prop: '',
label: '操作',
width: 200,
render: (h, params) => {
return (
<div>
<el-button
type='text'
onClick={() => this.handleModify(params.row)}
>
修改
</el-button>
<el-button
type='text'
onClick={() => this.handleDel(params.row)}
>
删除
</el-button>
</div>
)
}
}
],
}
},
methods: {
// 修改
handleModify(item) {
console.warn(item, '修改')
},
// 删除
handleDel(item) {
this.$confirm('确定删除么?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
console.warn(item, '删除')
})
},
// 初始化列表数据
refresh() {
this.listLoading = true
getList().then((response) => {
let start = (this.listQuery.data.page - 1) * this.listQuery.data.pagesize
let end = (this.listQuery.data.page - 1) * this.listQuery.data.pagesize + this.listQuery.data.pagesize
this.dataList = response.data.items.slice(start, end)
this.total = response.data.total
this.listLoading = false
})
},
}
}