直接上源码
<template>
<table class="my_table" :style="tableStyle">
<thead ref="header">
<tr :style="theadStyle">
<th v-for="(item, index) in new_columns" :key="item.unique || index"
:style="{minWidth: typeof item.minWidth === 'number'?item.minWidth + 'px':item.minWidth,
width: item.width + 'px',
textAlign: item.headAlign || 'center'}"
:title="item.title">
<slot :name="item.slotHeader" :data="{...item,index}">
{{item.title}}
</slot>
</th>
</tr>
</thead>
<tbody :style="tbodyStyle" ref="tableTbody">
<tr v-for="(item,index) in index_data" :key="(dataKey && item[dataKey]) || index" :style="newRowStyle(item,index)">
<td v-for="(_item, _index) in new_columns" :key="_item.unique || _index"
:style="{minWidth: typeof _item.minWidth === 'number'?_item.minWidth + 'px':_item.minWidth,
width: _item.width + 'px',
textAlign: _item.textAlign || 'center'}">
<slot :name="_item.slot" :data="{...item}">
{{chooseKey(item,_item.key)}}
</slot>
</td>
</tr>
</tbody>
</table>
</template>
<script>
export default {
name: 'MyList',
props: {
/* TODO columns接受值: 对象数组
title: 表头名称
slotHeader: 表头插槽名称
slot: 表体插槽
unique: 默认索引值,必须唯一,便于vue优化
key: 对应prop:{data}中数据的键值
minWidth: 对应列最小宽度
*/
columns: {
type: Array,
default: () => []
},
data: {
type: Array,
default: () => []
},
count: {//序号记数初值
type: Number || String,
default: 1
},
dataKey: {
type: String,
default: null
},
tbodyStyle: {//自定义tbody的style
type: String,
default: null
},
tableStyle: {
type: String,
default: null
},
theadStyle: {
type: String,
default: null
},
rowStyle: {//自定义tbody中tr的style
default: null
}
},
computed: {
new_columns () {//默认值并入columns
let newArr = []
for (let i = 0; i < this.columns.length; i++) {
newArr[i] = JSON.parse(JSON.stringify(this.columns[i]))
for (let j = 0; j < this.columns_list.length; j++) {
if (this.columns[i].title === this.columns_list[j].title) {
newArr[i] = (Object.assign(JSON.parse(JSON.stringify(this.columns_list[j])), this.columns[i]))
break
}
}
}
return newArr
},
index_data () {//序号处理
let newArr = this.data
newArr.map((item, index) => {
item.C_INDEX = index + (this.count * 1)
})
return newArr
}
},
watch: {
},
data: () => ({
columns_list: [//默认值
{
title: '序号',
width: '60',
key: 'C_INDEX'
},
{
title: '版面',
key: 'CHNLDESC',
width: '80'
},
{
title: '标题',
key: 'TITLE',
textAlign: 'left'
},
{
title: '类型',
key: 'DOCTYPE',
width: '60'
},
{
title: '稿件ID',
key: 'METADATAID',
width: '70'
},
{
title: '栏目',
key: 'CHNLDESC',
width: '120'
},
{
title: '操作人',
key: 'TRUENAME',
width: '86'
},
{
title: '状态',
key: 'STATUSNAME',
width: '72'
},
{
title: '最后版本时间',
key: 'OPERTIME',
width: '154'
},
{
title: '点击量',
key: 'HITS',
width: '70'
},
{
title: '流程版本时间',
key: 'OPERTIME',
width: '154'
},
{
title: '焦点图标题',
key: 'FOCUSIMGTITLE'
},
{
title: '焦点图描述',
key: 'FOCUSIMAGEDESC'
},
{
title: '稿件标题',
key: 'TITLE',
textAlign: 'left'
},
{
title: '渠道',
width: '120'
},
{
title: '字数',
key: 'DOCWORDSCOUNT',
width: '70'
},
{
title: '创建人',
key: 'TRUENAME',
width: '90'
},
{
title: '传稿人',
key: 'OPERNAME',
width: '90'
},
{
title: '产品',
key: ['SITEDESC', 'ACCOUNTNAME'],
width: '90'
},
{
title: '指派人',
key: 'TRUENAME',
width: '90'
},
{
title: '所有者',
key: 'OWNERTRUENAME',
width: '86'
},
{
title: '作者',
key: 'AUTHOR_TRUENAME',
width: '86'
},
{
title: '修改时间',
key: 'OPERTIME',
width: '154'
}
]
}),
methods: {
evil (code) {
let Fn = Function // 一个变量指向Function,防止有些前端编译工具报错
return new Fn('return ' + code)()
},
newRowStyle (item, index) {//rowStyle处理
if (typeof (this.rowStyle) === 'string') {
return this.rowStyle
} else if (typeof (this.rowStyle) === 'object' && (this.rowStyle.field && this.rowStyle.symbol && this.rowStyle.condition)) {
if (this.evil("'" + this.chooseKey(item, this.rowStyle.field) + "'" + this.rowStyle.symbol + "'" + this.rowStyle.condition + "'")) {
return this.rowStyle.style
}
}
},
chooseKey (item, keyArr) {//数组key处理
if (Object.prototype.toString.call(keyArr) === '[object Array]') {
for (let i = 0; i < keyArr.length; i++) {
if (!(item[keyArr[i]] === '' || item[keyArr[i]] === undefined || item[keyArr[i]] === null)) {
return item[keyArr[i]]
}
}
} else if (Object.prototype.toString.call(keyArr) === '[object String]') {
return item[keyArr]
}
}
}
}
</script>
<style lang="less">
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.my_table{
width: 100%;
height: 100%;
}
.my_table thead tr{
border-top: 1px solid #eff1f4;
color: #2a2a2a;
}
.my_table thead tr th{
font-size: 16px;
font-weight: 500;
padding: 14px 0;
padding-left: 5px;
padding-right: 5px;
}
.my_table tbody{
overflow-y: 'auto'
}
.my_table tbody tr:nth-child(odd) {
background: #f4f6f7;
}
.my_table tbody tr {
border-top: 1px solid #fff;
border-bottom: 1px solid #fff;
color: #3d3d3d;
&:hover{
background-color: #f4e0e1!important;
}
}
.my_table tbody tr td {
padding-left: 3px;
padding-right: 1px;
padding-top: 7px;
padding-bottom: 7px;
font-size: 14px;
text-align: center;
word-break: break-all;
height: 45px;
min-height: 45px;
max-height: 50px;
}
</style>
参数表:
使用示例:
<template>
<div class="ceshi">
<CList :columns='columns' :data='data' tableStyle='' theadStyle='' tbodyStyle='' :rowStyle='rowStyle'>
<template v-slot:TITLE='item'>
<a class="title" href="../../">{{item.data.TITLE}}</a>
<span class="mark" v-if="item.data.ORIGINAL==='1'" title="原创稿">原</span>
</template>
<template v-slot:WEBSTATUSNAME='item'>
<span v-if="item.data.WEBSTATUSNAME==='待编'" style="color: #ffbe5c;">{{item.data.WEBSTATUSNAME}}</span>
<span v-else-if="item.data.WEBSTATUSNAME==='撤稿'" style="color: #d64541;">{{item.data.WEBSTATUSNAME}}</span>
</template>
<template v-slot:OPERTIME='item'>
<a class="title" href="../../">{{item.data.OPERTIME}}</a>
</template>
</CList>
</div>
</template>
<script>
import CList from '@/components/MyList'
export default {
name: 'List',
data: () => ({
columns: [],
data: [],
rowStyle: {
field: `WEBSTATUSNAME`,
symbol: `===`,
condition: `待修订`,
style: 'color:#ccc'
}
}),
components: {
CList
},
mounted () {
this.getData_dzbcs()
},
methods: {
getData_dzbcs () {
this.$axios.get('../../static/wangzhan.json').then(response => {
this.columns = [
{
title: '序号'
},
{
title: '稿件ID'
},
{
title: '标题',
slot: 'TITLE'
},
{
title: '类型'
},
{
title: '栏目'
},
{
title: '操作人'
},
{
title: '作者'
},
{
title: '状态',
slot: 'WEBSTATUSNAME',
key: 'WEBSTATUSNAME'
},
{
title: '最后版本时间',
slot: 'OPERTIME'
}
]
this.data = response.data.DATA
}, response => {
console.log('error')
})
}
}
}
</script>
<style lang="less" scoped>
.ceshi{
width: 1713px;
}
a.title{
vertical-align: middle;
display: inline;
overflow: hidden;
line-height: 21px;
display: initial;
color: #3d3d3d;
text-decoration: none;
cursor: pointer;
&:hover{
color: #d64541;
}
}
.mark{
color: #c2c5cd;
border-color: #c2c5cd;
font-size: 11px;
cursor: pointer;
margin-left: 7px;
display: inline-block;
width: 16px;
height: 16px;
border: 1px solid;
text-align: center;
line-height: 16px;
border-radius: 2px;
}
</style>
效果: