vue2
table表格
因某些原因,开发时总是需要在h5页面上开发表格, 所以就自己封装了一个, 这样就便于维护.一下直接提供源码, 不足之处, 请不吝赐教.
先来看看效果图:
以下为源码:
<template>
<div
class="cuTable"
:style="{
...scroll && {
overflowX: 'scroll'
},
...!scroll && {
overflow: 'hidden'
}
}"
>
<div :class="border ? 't-table_border' : ''">
<table :class="round ? 't-table_th_round' : ''">
<tr v-if="tableTitle">
<th :colspan="params.length"
:style="{
background: hBgColor,
borderBottom: 'none',
color: '#232A33',
fontSize: '14px'
}"
>
{{ tableTitle }}
</th>
</tr>
<tr>
<th v-for="(item, index) in params"
:style="{
width: item.width ? item.width : 'auto',
height: rowHeight,
background: hBgColor,
color: hColor,
textAlign: align,
whiteSpace: scroll ? 'nowrap' : 'wrap'
}"
:key="index+'p'"
>
<span :style="{whiteSpace: item.whiteSpace ? 'wrap' : 'nowrap'}">{{ item.title }}</span>
</th>
</tr>
<tr
v-show="list && list.length > 0"
v-for="(item, index) in list"
:key="index+'p1'"
@click="rowClick(item)"
:style="{
background: rowBgColor && (index%2 !== 0 ? rowBgColor : '#fff'),
}"
>
<td
v-for="(ite, idx) in params"
:key="idx+'p2'"
:style="{
textAlign: align,
wordBreak: scroll ? '' : 'break-word',
}"
>
<span v-if="wordWrap && wordWrap === ite.labelKey" style="white-space: nowrap">{{
item[ite.labelKey]
}}</span>
<span v-else>{{ item[ite.labelKey] }}</span>
</td>
</tr>
<tr v-if="list.length === 0">
<td :colspan="params.length">
<slot name="empty">
<div style="color: #666; font-size: 14px; padding: 6px; text-align: center">暂无数据</div>
</slot>
</td>
</tr>
</table>
</div>
</div>
</template>
<script>
export default {
name: "cuTable",
data() {
return {
list: []
}
},
props: {
params: { // 配置参数 title: 标题, labelKey: 数据取值的key width: 表格宽度, whiteSpace: 标题是否换行
type: Array,
default: () => {
return ([])
}
},
dataSource: { // 数据
type: Array,
default: () => {
return ([])
}
},
tableTitle: { // 表格标题
type: String
},
wordWrap: { // 表格项数据不换行, key
type: String
},
border: { // 边框
type: Boolean,
default: true
},
scroll: { // 左右滑动
type: Boolean,
default: true
},
round: { // 边框圆角
type: Boolean,
default: true
},
borderColor: { // 边框颜色
type: String,
default: '#D4E6FF'
},
hBgColor: { // 头背景颜色
type: String,
default: '#EDF5FF'
},
hColor: { // 头字体颜色
type: String,
default: '#868C94'
},
align: { // 文字对齐方式
type: String,
default: 'left'
},
rowHeight: { // 行高
type: String,
default: '31px'
},
rowBgColor: { // 行背景色 n+1行
type: [String, Boolean],
default: '#fff'
},
format: { // 格式
type: String,
default: 'YYYY.MM.DD'
},
formatKey: {
type: String,
default: "PREM_DUE_DATE"
},
},
watch: {
dataSource: {
deep: true,
handler(newV, oldV) {
if (newV !== oldV) {
this.initData()
}
}
}
},
mounted() {
this.initData()
},
methods: {
initData() {
this.list = JSON.parse(JSON.stringify(this.dataSource))
if (this.format && this.formatKey) {
this.list.map(item => {
if (item[this.formatKey] && item[this.formatKey].indexOf('9999') > -1) {
item[this.formatKey] = '终身'
} else {
let date = new Date(item[this.formatKey]);
if (date) {
let y = date.getFullYear()
let m = date.getMonth() + 1 > 9 ? date.getMonth() + 1 : `0${date.getMonth() + 1}`
let d = date.getDate() + 1 > 9 ? date.getDate() + 1 : `0${date.getDate() + 1}`
let h = date.getHours() + 1 > 9 ? date.getHours() + 1 : `0${date.getHours() + 1}`
let ms = date.getMinutes() + 1 > 9 ? date.getMinutes() + 1 : `0${date.getMinutes() + 1}`
let s = date.getSeconds() + 1 > 9 ? date.getSeconds() + 1 : `0${date.getSeconds() + 1}`
if (this.format === 'YYYY.MM.DD') {
item[this.formatKey] = `${y}.${m}.${d}`
}
if (this.format === 'YYYY.MM.DD hh:mm:ss') {
item[this.formatKey] = `${y}.${m}.${d} ${h}:${ms}:${s}`
}
if (this.format === 'YYYY-MM-DD') {
item[this.formatKey] = `${y}-${m}-${d}`
}
if (this.format === 'YYYY-MM-DD hh:mm:ss') {
item[this.formatKey] = `${y}-${m}-${d} ${h}:${ms}:${s}`
}
}
}
})
}
},
rowClick(row) {
this.$emit('onClick', row)
},
}
}
</script>
<style lang="less" scoped>
table {
width: 100%;
margin: auto;
border-spacing: 0;
font-size: 14px;
}
.t-table_border {
table {
width: 100%;
margin: auto;
border-spacing: 0;
font-size: 14px;
}
table tr > th {
text-align: center;
border: 1px solid #D4E6FF;
padding: 4px;
}
table tr > th:nth-child(2n) {
border-right: none;
border-left: none;
}
table tr > th:last-child {
border-right: 1px solid #D4E6FF;
}
table tr > td {
text-align: center;
border: 1px solid #D4E6FF;
border-top: none;
padding: 4px;
}
table tr > td:nth-child(2n) {
border-right: none;
border-left: none;
}
table tr > td:last-child {
border-right: 1px solid #D4E6FF;
}
}
.t-table_th_round {
tr:first-child th:first-child {
border-top-left-radius: 8px;
}
tr:first-child th:last-child {
border-top-right-radius: 8px;
}
tr:last-child {
td:first-child {
border-bottom-left-radius: 8px;
}
}
tr:last-child {
td:last-child {
border-bottom-right-radius: 8px;
}
}
}
</style>
往下是使用例子:
<cuTable
:tableTitle="`${ item.clientName }的个人${ type }`"
:params="params"
:data-source="dataSource"
wordWrap="enddate"
/>
data() {
return {
dataSource: [{liaBesc: '保险'}, {liaBexp: '保额(万元)'}, endDate: "2022-02-01"}],
params: [{
title: '保险责任',
labelKey: 'liaBesc'
}, {
title: '保额(万元)',
labelKey: 'liaBexp',
whiteSpace: false
}, {
title: '保险期间',
labelKey: 'endDate'
}]
}