先来看看展示效果
image.png
项目需求
- 展示基础表格
- 在每一列数据中,如果只有正值,则表格左侧为0坐标,以最大值为表格全部宽度,其他按照比例去展示
- 有正负值,需要计算0坐标位置,根据最大值最小值去确定坐标位置,根据正负值展示图形
- 负值图形颜色为红色,正值颜色根据外部传入参数确定颜色,默认蓝色
表格组件
<template>
<div class="table-content-container">
<div class="tableHeader">
<div
class="fontCommon"
v-for="(item, index) in data.column"
:key="index"
:style="{'width': item.width + 'px','text-align': item.align ? item.align : 'left'}"
>
{{ item.name}}
</div>
</div>
<div class="table-content" :style="'height:' + height + 'px'">
<ul class="ul-scoll">
<li
v-for="(item, index) in data.data"
:key="index"
@click="handleRow(item, index)"
>
<div
v-for="(list, i) in data.column"
:key="i"
:style="'width:' + list.width + 'px'"
>
<!--普通表格列-->
<p
v-if="list.text"
class="text"
:style="{
color: changeColor(list, item[list.prop], item),
'text-align': list.align ? list.align : 'left',
}"
>
{{ item[list.prop] }}
</p>
<!--包含图表的列-->
<div
v-else
class="text"
:style="{
color: changeColor(list, item[list.prop], item),
'text-align': list.align ? list.align : 'left',
}"
>
{{ item[list.prop] || '-' }}
<!--图形-->
<div
class="progress"
:class="item[list.prop]<0?'red':list.chartClass?list.chartClass:'blue'"
:style="getProgressStyle(list,item)"
></div>
</div>
</div>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
name: 'tableContent',
props: {
data: {
type: Object,
default: () => {
return {
column: [],
data: []
};
},
},
height: {
type: Number,
default: 400,
},
loading: {
type: Boolean,
default: false,
}
},
watch: {
data: {
handler () {
this.changeData()
},
deep: true,
immediate: true
}
},
mounted () {
},
methods: {
changeData () {
this.data.column.forEach((item, index) => {
if (item.hasChart) {
const arr = this.data.data.map(i => {
return i[item.prop]
})
const maxNum = Math.max(...arr)
const minNum = Math.min(...arr)
item.maxNum = maxNum
item.minNum = minNum
}
})
},
changeColor (list) {
return list.color || '#DFDFE0'
},
getProgressStyle (list, item) {
if (list.minNum < 0) {
const minNum = Math.abs(list.minNum)
const leftP = minNum / (minNum + list.maxNum)
const fWidth = leftP * list.width
const zWidth = list.width - fWidth
if (Number(item[list.prop]) >= 0) {
return `left:${ fWidth }px;width:${ Number(item[list.prop]) / list.maxNum * zWidth }px`
} else {
const itemW = Math.abs(item[list.prop]) / Math.abs(list.minNum) * fWidth
return `left:${ fWidth - itemW }px;width:${ itemW }px`
}
} else {
return `left:0;width:${ Number(item[list.prop]) / list.maxNum * list.width }px`
}
}
}
}
</script>
<style lang="scss" scoped>
.table-content-container {
.tableHeader {
width: 100%;
display: flex;
align-items: center;
.fontCommon {
color: #DFDFE0;
font-size: 14px;
line-height: 44px;
border-top: 1px solid #ccc;
border-right: 1px solid #ccc;
&:nth-of-type(1) {
padding-left: 10px;
border-left: 1px solid #ccc;
}
}
}
.table-content {
overflow-y: scroll;
width: 102%;
position: relative;
ul {
width: 98.2%;
li {
width: 100%;
height: 44px;
display: flex;
flex-direction: row;
&:nth-last-of-type(1) {
> div {
border-bottom: 1px solid #ccc;
}
}
> div {
border-top: 1px solid #ccc;
border-right: 1px solid #ccc;
&:nth-of-type(1) {
padding-left: 10px;
border-left: 1px solid #ccc;
}
}
.text {
font-size: 14px;
color: #cccccc;
line-height: 44px;
height: 44px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
position: relative;
padding-right: 6px;
.progress {
position: absolute;
top: 0;
height: 44px;
z-index: 1;
&.red {
background: linear-gradient(to right, #e75e5e, rgba(231, 94, 94, 0.2));
}
&.blue {
background: linear-gradient(to right, #5eb9e3, rgba(94, 185, 227, 0.2));
}
&.origin {
background: linear-gradient(to right, #e79e5e, rgba(231, 158, 94, 0.2));
}
&.green {
background: linear-gradient(to right, #78db67, rgba(120, 219, 103, 0.2));
}
}
&.pointer {
cursor: pointer;
}
}
}
}
}
::-webkit-scrollbar {
width: 4px;
}
::-webkit-scrollbar-track {
background: transparent;
border-radius: 0;
}
::-webkit-scrollbar-thumb {
background: #475e8f;
border-radius: 2px;
}
}
@keyframes loading {
0% {
transform: rotate(0);
}
50% {
transform: rotate(180deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
传入的参数样式
data参数示例:
data:{
column: [ //表头列明,和列的规则
{
name: "分析项目",
prop: "name",
width: 140,
text: true
},
{
name: "入库税金(万元)",
prop: "value1",
width: 160, //列宽
hasChart: 'true', //是否展示图形
chartClass: 'origin', //图形正数据的颜色
align: 'right' //列文字居左还是居右
},
{
name: "利息(%)",
prop: "value2",
width: 160,
hasChart: 'true',
chartClass: 'green',
align: 'right'
},
{
name: "总营业额(万元)",
prop: "value3",
width: 160,
hasChart: 'true',
chartClass: 'blue',
align: 'right'
}
],
data: [
{
name: '央行借款',
value1: 100,
value2: 0,
value3: 1000,
},
{
name: '央行借款',
value1: -20,
value2: -55,
value3: 5555
},
{
name: '央行借款',
value1: 20,
value2: 23,
value3: 1937,
},
{
name: '央行借款',
value1: -50,
value2: 40,
value3: 400
}
]
}
- 表头属性
name: 表头名称,
prop:列数据对应的参数名,
width: 160, //列宽
hasChart: 'true', //列是否展示图形
chartClass: 'origin', //列图形正数据的颜色
align: 'right' //列文字居左还是居右