实现效果:

封装组件:
<template>
<div class="app-container">
<el-table
ref="multipleTable"
:data="data"
tooltip-effect="dark"
style="width: 100%"
:fit="tableAttribute.fit"
:border="tableAttribute.border"
:size="tableAttribute.size"
:highlight-current-row="tableAttribute.highlightCurrentRow"
@selection-change="handleSelectionChange"
>
<el-table-column
:type="TableSelect.type"
:width="TableSelect.width"
v-if="TableSelect.select"
>
</el-table-column>
<el-table-column
v-for="(item,index) in tableHeader"
:key="index"
:prop="item.prop"
:label="item.label"
:width="item.width"
:align="item.align"
:show-overflow-tooltip="true"
>
<template slot-scope="scope">
<template v-if="!item.dataType && !item.render">
{{ scope.row[item.prop]}}
</template>
<template v-if="item.dataType && item.dataType=='img'">
<el-image
lazy
:src="item.render(data[scope.$index][item.prop],scope.row)"
style="width: 70px; height: 70px"
:preview-src-list="preview(data[scope.$index][item.prop])"
/>
</template>
<template v-if="item.render && !item.dataType">
{{ item.render(data[scope.$index][item.prop],scope.row)}}
</template>
</template>
</el-table-column>
<slot></slot>
</el-table>
<el-pagination
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[5, 10, 20, 30, 40]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
>
</el-pagination>
</div>
</template>
<script>
export default {
props: {
render: {
type: Function,
},
param: {
type: Object,
},
tableAttribute: {
type: Object,
default: () => {},
required: true
},
data: {
type: Array,
default: () => [],
required: true
},
tableHeader: {
type: Array,
default: () => [],
required: true
},
TableSelect: {
type: Object,
default: () => {},
required: true
},
total: {
type: Number,
default: 20,
},
page: {
type: Number,
default: 1,
},
limit: {
type: Number,
default: 10,
},
},
render(h) {
return this.render(h, this.param)
},
computed: {
currentPage: {
get() {
return this.page
},
set(val) {
this.$emit('update:page', val)
},
},
pageSize: {
get() {
return this.limit
},
set(val) {
this.$emit('update:limit', val)
},
},
},
methods: {
handleSelectionChange(val) {
console.log('选中的值:', val)
},
handleSizeChange(limit) {
this.$emit('pagination', { page: this.currentPage, limit: limit })
},
handleCurrentChange(page) {
this.$emit('pagination', { page: page, limit: this.pageSize })
},
preview(val) {
let arr = []
arr.push(val)
return arr
},
},
}
</script>
<style scoped>
.app-container {
margin: 100px auto;
}
.btn {
display: flex;
justify-content: flex-end;
margin: 0 40px 20px 0;
}
.el-pagination {
text-align: center;
margin-top: 40px;
}
</style>
引用组件:
<template>
<div>
<dynamic-table
:total="total"
:data="tableData"
:TableSelect="TableSelect"
:tableHeader="tableHeader"
:tableAttribute="tableAttribute"
:page.sync="queryParams.page"
:limit.sync="queryParams.limit"
@pagination="getList"
>
<template>
<el-table-column
label="操作"
style="width:120px;"
>
<template slot-scope="scope">
<el-button
type="text"
@click="viewClick(scope.row)"
>查看</el-button>
<el-button
type="text"
@click="editClick(scope.row)"
>编辑</el-button>
</template>
</el-table-column>
</template>
</dynamic-table>
</div>
</template>
<script>
import DynamicTable from './DynamicTable.vue'
import axios from 'axios'
export default {
components: {
DynamicTable,
},
data() {
return {
queryParams: {
page: 1,
limit: 10,
},
total: 20,
tableAttribute: {
stripe: true,
border: true,
fit: true,
highlightCurrentRow: true,
size: 'small',
align:'center'
},
tableHeader: [
{ prop: 'serialTime', label: '连载时间', align: 'center' },
{ prop: 'endTime', label: '完结时间', align: 'left' },
{ prop: 'novel', label: '小说名', align: 'left' },
{ prop: 'protagonist', label: '主角', align: 'center' },
{
prop: 'sex',
label: '性别',
render: (text, row) => {
return row.sex == true ? '男' : '女'
},
align: 'center'
},
{ prop: 'serialPlatform', label: '连载平台' },
{ prop: 'totalWords', label: '总字数(万)',align: 'right' },
{
prop: 'img',
label: '图片',
dataType: 'img',
render: (text, row) => {
if (row.echoMap) {
return row.echoMap.img.src
} else {
return row.img
}
},
align: 'center'
},
{
prop: 'dec',
label: '描述',
previewDec: (row, col, cellValue) => {
return row
},
},
],
tableData: [],
TableSelect: {
select: true,
type: 'selection',
width: 60,
align:'center'
},
}
},
mounted() {
this.getData()
},
methods: {
render(h, params) {
return h('span', null, '我是一个render组件')
},
getList() {
this.total = this.tableData.length
},
viewClick(val) {
console.log('查看', val)
},
editClick(val) {
console.log('编辑', val)
},
getData(){
axios.post("http://localhost:8080/goods/goodAll").then((res)=>{
console.log(res.data.data)
this.tableData=res.data.data
this.getList()
})
},
},
}
</script>
<style>
</style>
mock.js:
const Mock = require('mockjs')
let Random = Mock.Random
let data = Mock.mock({
"data|10": [
{
"novelId|+1": 1,
"serialTime": '@date',
"endTime": '@date',
"novel": '《' + Random.cword(4, 7) + '》',
"protagonist": Random.cname(),
"sex|1-2": true,
'serialPlatform': Random.cword(4, 6),
"totalWords|500-700": 1,
"img": Random.image('400x600', '#894FC4'),
"dec": Random.cparagraph(30, 60),
}
]
})
Mock.mock(/goods\/goodAll/, 'post', () => {
return data
})
安装axios库,并在main.js中将axios挂载到vue实例中:
import axios from 'axios'
Vue.prototype.$http = axios