Commit 57bb82ac authored by leon's avatar leon

feat:table add table cell style

parent 927bd1b8
<template>
<view class="normal-table">
<NormalTitle :elementInfo="elementInfo"></NormalTitle>
<scroll-view scroll-x scroll-y class="scroll-view_H" :style="[tableConfigStyle]">
<view class="table">
<view class= 'tr' :class="[sticky ? 'table_header_sticky' : 'table_header']" v-if="elementInfo.table.tableHeader.showHeader">
<template v-for="(item, index) in elementInfo.table.column">
<view
class="th th_style"
:class="[index == 0 && !sticky ? 'row_fixed': '']"
:key="index"
>{{item.title}}</view>
</template>
</view>
<view
class="tr"
v-for="(cell, cellIndex) in chartTables"
:key="cellIndex"
:class="elementInfo.table.tableCell.stripes? (cellIndex % 2 === 1 ? 'even-striped' : 'odd-striped'): null"
@tap="cellClick(cell)"
>
<view
v-for="(item, index) in elementInfo.table.column"
:key="index"
class="td td_style"
:class="[item.dataIndex == elementInfo.table.column[0].dataIndex ? 'row_fixed': '']"
>
<template v-if="item.slots.customRender == 'rank'">{{index + 1}}</template>
<template v-else-if="item.slots.customRender == 'picture'">
<u-image
:height="100"
mode="aspectFit"
:src="`${cell[item.dataIndex]}?${new Date().getTime()}`"
crossOrigin="anonymous"
style="width:100%"
@click="imageClick(cellIndex, item.dataIndex)"
></u-image>
</template>
<template v-else-if="item.slots.customRender == 'toThousands'">{{$u.common.toThousands(cell[item.dataIndex])}}</template>
<template v-else-if="item.slots.customRender == 'percentage'">{{Number(cell[item.dataIndex] * 100).toFixed(0)}}%</template>
<template v-else-if="item.slots.customRender == 'Integer'">{{parseInt(cell[item.dataIndex])}}</template>
<template v-else-if="item.slots.customRender == 'price'">{{`¥${Number(cell[item.dataIndex]).toFixed(2)}`}}</template>
<template v-else>{{cell[item.dataIndex]}}</template>
</view>
</view>
</view>
</scroll-view>
</view>
</template>
<script>
import echartElementData from '@/mixins/echartElementData.js'
export default {
name:"NormalTable",
mixins: [echartElementData],
data() {
return {
chartTables: [],
align: {
left: 'start',
center: 'center',
right: 'flex-end'
},
sticky: false
};
},
computed: {
tableConfigStyle() {
const { frameStyle, frameWidth, frameColor, bordered } = this.elementInfo.table
const { evenColor, oddColor, backgroundColor: cellBackgroundColor, titlePostion: cellTitlePostion, titleFontSize: cellTitleFontSize, cellRowHeight, titleColor: cellTitleColor} = this.elementInfo.table.tableCell
const { headerRowHeight, titleColor: headerTitleColor, backgroundColor: headerBackgroundColor, titlePostion: headerTitlePostion, titleFontSize: headerTitleFontSize } = this.elementInfo.table.tableHeader
const cellWidth = this.elementInfo.table.column.length > 10 ? 130 : 240
return {
'--table-width': `${cellWidth * this.elementInfo.table.column.length}rpx`,
'--cell-width': `0 0 ${cellWidth}rpx`,
'--cell--background-color': cellBackgroundColor,
'--even-color': evenColor,
'--odd-color': oddColor,
'--header-background-color': headerBackgroundColor,
'--header-row-height': `${headerRowHeight}px`,
'--header-color': headerTitleColor,
'--header-font-size': `${this.$u.common.pxToRpx(headerTitleFontSize)}rpx`,
'--header-text-align': headerTitlePostion || 'center',
'--header-border': bordered ? `${frameStyle || 'solid'} ${frameWidth || 1}px ${frameColor || '#e4e7ed'}`: 'none',
'--cell-text-align': cellTitlePostion,
'--cell-justify-content': this.align[cellTitlePostion],
'--cell-font-size': `${cellTitleFontSize || 14}px`,
'--cell-row-height': `${cellRowHeight || 30}px`,
'--cell-color': cellTitleColor
}
},
},
mounted() {
uni.$on(this.elementInfo.id, ({sticky}) => {
this.sticky = sticky
})
},
destroyed() {
uni.$off(elementInfo.id)
},
methods: {
initChart() {
const that = this
that.$nextTick(() => {
that.chartTables = that.elementData.dataList.chartTables
})
},
cellClick(e) {
const { index, data } = this.elementInfo.child
const paramName = this.elementInfo.table.primaryKey
const value = e[paramName]
uni.$emit('handleLinkParams', { index, paramName, value: value })
},
// 图片增加点击事件,查看全部图片
imageClick(index, key) {
const images = []
var caches = uni.getStorageSync('cacheImages')
for(var i = 0; i < this.chartTables.length; i++) {
const imageUrl = this.chartTables[i][key]
if(caches.hasOwnProperty(imageUrl)) {
images.push(caches[imageUrl])
} else {
images.push(imageUrl)
}
}
uni.previewImage({
current: index,
urls: images
})
},
/**
* 缓存图片数据
*/
cacheImages(key) {
var caches = uni.getStorageSync('cacheImages')
if(!caches) {
caches = {}
}
this.chartTables.forEach(item => {
// 如果包含当前url,就不再下载
const url = item[key]
if(!caches.hasOwnProperty(url)) {
uni.downloadFile({
url: url,
success: (res) => {
if(res.statusCode === 200) {
caches[url] = res.tempFilePath
uni.setStorageSync('cacheImages', caches)
<template>
<view class="normal-table">
<NormalTitle :elementInfo="elementInfo"></NormalTitle>
<scroll-view scroll-x scroll-y class="scroll-view_H" :style="[tableConfigStyle]">
<view class="table">
<view class='tr' :class="[sticky ? 'table_header_sticky' : 'table_header']"
v-if="elementInfo.table.tableHeader.showHeader">
<template v-for="(item, index) in elementInfo.table.column">
<view class="th th_style" :class="[index == 0 && !sticky ? 'row_fixed': '']" :key="index">
{{item.title}}
</view>
</template>
</view>
<view class="tr" v-for="(cell, cellIndex) in chartTables" :key="cellIndex"
:class="elementInfo.table.tableCell.stripes? (cellIndex % 2 === 1 ? 'even-striped' : 'odd-striped'): null"
@tap="cellClick(cell)">
<view v-for="(item, index) in elementInfo.table.column" :key="index" class="td td_style"
:class="[item.dataIndex == elementInfo.table.column[0].dataIndex ? 'row_fixed': '']"
:style="[tableCellStyle(index, cellIndex)]" :data-column="index" :data-row="cellIndex">
<template v-if="item.slots.customRender == 'rank'">{{index + 1}}</template>
<template v-else-if="item.slots.customRender == 'picture'">
<u-image :height="100" mode="aspectFit"
:src="`${cell[item.dataIndex]}?${new Date().getTime()}`" crossOrigin="anonymous"
style="width:100%" @click="imageClick(cellIndex, item.dataIndex)"></u-image>
</template>
<template
v-else-if="item.slots.customRender == 'toThousands'">{{$u.common.toThousands(cell[item.dataIndex])}}</template>
<template
v-else-if="item.slots.customRender == 'percentage'">{{Number(cell[item.dataIndex] * 100).toFixed(0)}}%</template>
<template
v-else-if="item.slots.customRender == 'Integer'">{{parseInt(cell[item.dataIndex])}}</template>
<template
v-else-if="item.slots.customRender == 'price'">{{`¥${Number(cell[item.dataIndex]).toFixed(2)}`}}</template>
<template v-else>{{cell[item.dataIndex]}}</template>
</view>
</view>
</view>
</scroll-view>
</view>
</template>
<script>
import echartElementData from '@/mixins/echartElementData.js'
export default {
name: "NormalTable",
mixins: [echartElementData],
data() {
return {
chartTables: [],
align: {
left: 'start',
center: 'center',
right: 'flex-end'
},
sticky: false
};
},
computed: {
tableConfigStyle() {
const {
frameStyle,
frameWidth,
frameColor,
bordered
} = this.elementInfo.table
const {
evenColor,
oddColor,
backgroundColor: cellBackgroundColor,
titlePostion: cellTitlePostion,
titleFontSize: cellTitleFontSize,
cellRowHeight,
titleColor: cellTitleColor
} = this.elementInfo.table.tableCell
const {
headerRowHeight,
titleColor: headerTitleColor,
backgroundColor: headerBackgroundColor,
titlePostion: headerTitlePostion,
titleFontSize: headerTitleFontSize
} = this.elementInfo.table.tableHeader
const cellWidth = this.elementInfo.table.column.length > 10 ? 130 : 240
return {
'--table-width': `${cellWidth * this.elementInfo.table.column.length}rpx`,
'--cell-width': `0 0 ${cellWidth}rpx`,
'--cell--background-color': cellBackgroundColor,
'--even-color': evenColor,
'--odd-color': oddColor,
'--header-background-color': headerBackgroundColor,
'--header-row-height': `${headerRowHeight}px`,
'--header-color': headerTitleColor,
'--header-font-size': `${this.$u.common.pxToRpx(headerTitleFontSize)}rpx`,
'--header-text-align': headerTitlePostion || 'center',
'--header-border': bordered ?
`${frameStyle || 'solid'} ${frameWidth || 1}px ${frameColor || '#e4e7ed'}` : 'none',
'--cell-text-align': cellTitlePostion,
'--cell-justify-content': this.align[cellTitlePostion],
'--cell-font-size': `${cellTitleFontSize || 14}px`,
'--cell-row-height': `${cellRowHeight || 30}px`,
'--cell-color': cellTitleColor
}
},
},
mounted() {
uni.$on(this.elementInfo.id, ({
sticky
}) => {
this.sticky = sticky
})
},
destroyed() {
uni.$off(elementInfo.id)
},
methods: {
initChart() {
const that = this
that.$nextTick(() => {
if (that.elementData.dataList.columns) {
const columns = that.elementData.dataList.columns.map(item => {
if (!item.slots) {
item.slots = {
customRender: ''
}
}
return item
})
}
})
}
}
}
</script>
<style scoped lang="scss">
.normal-table {
width: 100%;
height: calc(100% - 20px);
margin-top: 20px;
}
.scroll-view_H {
display: flex;
flex-wrap: nowrap;
width: 100%;
height: 100%;
}
.table {
width: var(--table-width);
box-sizing: border-box;
background-color: var(--cell--background-color);
.table_header {
position: sticky;
top: 0;
z-index: 2;
}
.table_header_sticky {
position: fixed;
top: 0;
z-index: 2;
}
.row_fixed {
position: sticky;
left: 0;
z-index: 1;
}
}
.tr {
display: flex;
flex-direction: row;
}
.th {
flex: var(--cell-width);
font-size: 28rpx;
color: $u-main-color;
padding: 10px 0px;
background-color: rgb(245, 246, 248);
}
.td{
flex: var(--cell-width);
align-self: stretch;
padding: 10px 0px ;
font-size: 28rpx;
color: $u-content-color;
display: flex;
align-items: center;
justify-content: center;
}
.th_style {
line-height: var(--header-row-height);
font-size: var(--header-font-size);
color: var(--header-color);
background-color: var(--header-background-color);
text-align: var(--header-text-align);
border-bottom: var(--header-border);
}
.td_style {
text-align: var(--cell-text-align);
justify-content: var(--cell-justify-content);
font-size: var(--cell-font-size);
line-height: var(--cell-row-height);
color: var(--cell-color);
border-bottom: var(--header-border);
}
.even-striped, .even-striped .row_fixed {
background-color: var(--even-color);
}
.odd-striped, .odd-striped .row_fixed {
background-color: var(--odd-color);
}
</style>
\ No newline at end of file
that.elementInfo.table.column = columns
}
that.chartTables = that.elementData.dataList.chartTables
})
},
tableCellStyle(column, index) {
const that = this
const columns = that.elementInfo.table.column
const col = columns[column]
if (col && col.hasOwnProperty('condition')) {
const condition = col.condition
// 设置了单元格样式
if (condition && condition.length) {
var color = ''
var backgroundColor = ''
const data = that.chartTables[index]
const value = data[columns[column].dataIndex]
if (value) {
condition.forEach((item) => {
const op = item.op
const val = item.value
let flag = false
if (op === 'GTR' && value > val) {
flag = true
}
if (op === 'GEQ' && value >= val) {
flag = true
}
if (op === 'EQU' && value === val) {
flag = true
}
if (op === 'LSS' && value < val) {
flag = true
}
if (op === 'LEQ' && value <= val) {
flag = true
}
if (op === 'NEQ' && value != val) {
flag = true
}
if (op === 'CONT' && value.toString().includes(val)) {
flag = true
}
if (flag) {
color = item.color
backgroundColor = item.backgroundColor
}
})
}
if (color.length || backgroundColor.length) {
return {
color: color,
backgroundColor: backgroundColor
}
}
}
}
},
cellClick(e) {
const {
index,
data
} = this.elementInfo.child
const paramName = this.elementInfo.table.primaryKey
const value = e[paramName]
uni.$emit('handleLinkParams', {
index,
paramName,
value: value
})
},
// 图片增加点击事件,查看全部图片
imageClick(index, key) {
const images = []
var caches = uni.getStorageSync('cacheImages')
for (var i = 0; i < this.chartTables.length; i++) {
const imageUrl = this.chartTables[i][key]
if (caches.hasOwnProperty(imageUrl)) {
images.push(caches[imageUrl])
} else {
images.push(imageUrl)
}
}
uni.previewImage({
current: index,
urls: images
})
},
/**
* 缓存图片数据
*/
cacheImages(key) {
var caches = uni.getStorageSync('cacheImages')
if (!caches) {
caches = {}
}
this.chartTables.forEach(item => {
// 如果包含当前url,就不再下载
const url = item[key]
if (!caches.hasOwnProperty(url)) {
uni.downloadFile({
url: url,
success: (res) => {
if (res.statusCode === 200) {
caches[url] = res.tempFilePath
uni.setStorageSync('cacheImages', caches)
}
}
})
}
})
}
}
}
</script>
<style scoped lang="scss">
.normal-table {
width: 100%;
height: calc(100% - 20px);
margin-top: 20px;
}
.scroll-view_H {
display: flex;
flex-wrap: nowrap;
width: 100%;
height: 100%;
}
.table {
width: var(--table-width);
box-sizing: border-box;
background-color: var(--cell--background-color);
.table_header {
position: sticky;
top: 0;
z-index: 2;
}
.table_header_sticky {
position: fixed;
top: 0;
z-index: 2;
}
.row_fixed {
position: sticky;
left: 0;
z-index: 1;
}
}
.tr {
display: flex;
flex-direction: row;
}
.th {
flex: var(--cell-width);
font-size: 28rpx;
color: $u-main-color;
padding: 10px 0px;
background-color: rgb(245, 246, 248);
}
.td {
flex: var(--cell-width);
align-self: stretch;
padding: 10px 0px;
font-size: 28rpx;
color: $u-content-color;
display: flex;
align-items: center;
justify-content: center;
}
.th_style {
line-height: var(--header-row-height);
font-size: var(--header-font-size);
color: var(--header-color);
background-color: var(--header-background-color);
text-align: var(--header-text-align);
border-bottom: var(--header-border);
}
.td_style {
text-align: var(--cell-text-align);
justify-content: var(--cell-justify-content);
font-size: var(--cell-font-size);
line-height: var(--cell-row-height);
color: var(--cell-color);
border-bottom: var(--header-border);
}
.even-striped,
.even-striped .row_fixed {
background-color: var(--even-color);
}
.odd-striped,
.odd-striped .row_fixed {
background-color: var(--odd-color);
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment