DemuMesDataV/components/scrollBoard/index.vue

382 lines
8.6 KiB
Vue
Raw Normal View History

2018-12-08 19:05:46 +08:00
<template>
2018-12-19 10:33:59 +08:00
<div class="scroll-board" :ref="ref">
2018-12-08 19:05:46 +08:00
2019-01-16 16:56:11 +08:00
<loading v-if="!status" />
2018-12-08 19:05:46 +08:00
<template v-else>
2018-12-19 10:33:59 +08:00
<div class="title-container"
v-if="titleData"
:style="`background-color:${titleTrueBG};`">
<div :class="`title-item ${textTrueAlign[ti]}`"
v-for="(title, ti) in titleData" :key="title + ti"
:style="`width: ${columnTrueWidth[ti]};`">
{{ title }}
</div>
</div>
<div class="row-container">
<div :class="`row-item ${row.fade && 'fade'}`"
:style="`height: ${rowHeight}%;background-color:${row.index % 2 === 0 ? evenTrueBG : oddTrueBG};`"
v-for="(row, ri) in scrollData"
:key="row.data + ri">
<div :class="`row-item-info ${textTrueAlign[ii]}`"
v-for="(info, ii) in row.data"
2019-01-10 17:31:23 +08:00
:key="info + Math.random()">
2018-12-19 10:33:59 +08:00
2019-01-10 19:03:02 +08:00
<div @click="emitClickEvent(row, ii)" :class="`rii-width ${ii === 0 && index && 'index-container'}`" :style="`width: ${columnTrueWidth[ii]};`">
2018-12-19 10:33:59 +08:00
<template v-if="ii === 0 && index">
<div class="index" :style="`background-color:${titleTrueBG};`">{{ info }}</div>
</template>
2019-01-10 19:03:02 +08:00
<span v-else v-html="info" />
2018-12-19 10:33:59 +08:00
</div>
</div>
</div>
2018-12-08 19:05:46 +08:00
</div>
</template>
</div>
</template>
<script>
export default {
name: 'scroll-board',
2019-01-16 16:56:11 +08:00
props: ['data', 'index', 'rowNum', 'titleBG', 'waitTime', 'oddBG', 'evenBG', 'columnWidth', 'textAlign', 'carousel'],
2018-12-08 19:05:46 +08:00
data () {
return {
2018-12-19 10:33:59 +08:00
ref: `scroll-board-${(new Date()).getTime()}`,
container: '',
containerWH: [],
2019-01-16 16:56:11 +08:00
status: false,
2019-01-10 19:03:02 +08:00
reAnimationTimer: '',
doFadeTimer: '',
2019-01-09 18:42:51 +08:00
2018-12-19 10:33:59 +08:00
defaultRowNum: 5,
defaultTitleBG: '#00BAFF',
defaultOddBG: '#003B51',
defaultEvenBG: '#0A2732',
2019-01-10 17:31:23 +08:00
defaultWaitTime: 2000,
2018-12-19 10:33:59 +08:00
rowTrueNum: '',
rowHeight: '',
titleTrueBG: '',
oddTrueBG: '',
evenTrueBG: '',
columnTrueWidth: [],
textTrueAlign: [],
currentIndex: 0,
allRowNum: 0,
allColumnNum: 0,
titleData: '',
allRowData: [],
scrollData: []
2018-12-08 19:05:46 +08:00
}
},
watch: {
2019-01-16 16:56:11 +08:00
data () {
const { checkData, init } = this
2018-12-08 19:16:30 +08:00
2019-01-16 16:56:11 +08:00
checkData() && init()
2018-12-08 19:05:46 +08:00
}
},
methods: {
init () {
2019-01-16 16:56:11 +08:00
const { checkData, initDom, stopAnimation, dealData, calcConfig, getCurrentScrollData } = this
2018-12-19 10:33:59 +08:00
initDom()
2018-12-08 19:05:46 +08:00
2019-01-16 16:56:11 +08:00
if (!checkData()) return
2018-12-08 19:05:46 +08:00
2019-01-09 18:42:51 +08:00
stopAnimation()
2018-12-19 10:33:59 +08:00
dealData()
2018-12-08 19:05:46 +08:00
2018-12-19 10:33:59 +08:00
calcConfig()
getCurrentScrollData(true)
2018-12-08 19:05:46 +08:00
},
2018-12-19 10:33:59 +08:00
initDom () {
const { $refs, ref } = this
const container = this.container = $refs[ref]
this.containerWH[0] = container.clientWidth
this.containerWH[1] = container.clientHeight
},
2019-01-16 16:56:11 +08:00
checkData () {
const { data } = this
this.status = false
if (!data || !data.series) return false
this.status = true
return true
},
2018-12-19 10:33:59 +08:00
dealData () {
2019-01-16 16:56:11 +08:00
const { data: { series, title }, index, deepClone } = this
2018-12-19 10:33:59 +08:00
if (title) (this.titleData = index ? ['', ...title] : [...title])
2019-01-16 16:56:11 +08:00
this.allRowData = deepClone(series).map((row, i) =>
2018-12-19 10:33:59 +08:00
({ index: i + 1, data: index ? [i + 1, ...row] : row }))
},
calcConfig () {
const { calcAllRowColumnNum, calcRowNum, calcRowHeight } = this
calcAllRowColumnNum()
calcRowNum()
calcRowHeight()
const { calcTitleBG, oddAndEvenRowBG, calcColumnWidth } = this
calcTitleBG()
oddAndEvenRowBG()
calcColumnWidth()
const { calcTextAlign } = this
calcTextAlign()
},
calcAllRowColumnNum () {
2019-01-16 16:56:11 +08:00
const { data: { series }, index } = this
2018-12-19 10:33:59 +08:00
2019-01-16 16:56:11 +08:00
this.allRowNum = series.length
2018-12-19 10:33:59 +08:00
2019-01-16 16:56:11 +08:00
this.allColumnNum = series[0].length + (index ? 1 : 0)
2018-12-19 10:33:59 +08:00
},
calcRowNum () {
const { rowNum, defaultRowNum } = this
this.rowTrueNum = parseInt(rowNum || defaultRowNum)
},
calcRowHeight () {
const { rowTrueNum } = this
this.rowHeight = 100 / rowTrueNum
},
calcTitleBG () {
const { titleBG, defaultTitleBG } = this
this.titleTrueBG = titleBG || defaultTitleBG
},
oddAndEvenRowBG () {
const { oddBG, evenBG, defaultOddBG, defaultEvenBG } = this
this.oddTrueBG = oddBG || defaultOddBG
this.evenTrueBG = evenBG || defaultEvenBG
},
calcColumnWidth () {
const { columnWidth, allColumnNum, filterNull, multipleSum, containerWH: [allWidth] } = this
const userSetColumnWidth = columnWidth || []
const setColumnData = filterNull(userSetColumnWidth)
const useWidth = multipleSum(...setColumnData.map(w => parseInt(w)))
const avgNum = allColumnNum - setColumnData.length
const avgWidth = (allWidth - useWidth) / avgNum + 'px'
this.columnTrueWidth = new Array(allColumnNum).fill(0).map((t, i) =>
userSetColumnWidth[i] ? `${userSetColumnWidth[i]}px` : avgWidth)
},
calcTextAlign () {
const { textAlign, allColumnNum, index } = this
const userSetTextAlign = textAlign || []
2018-12-08 19:05:46 +08:00
2018-12-19 10:33:59 +08:00
const textTrueAlign = new Array(allColumnNum).fill('left').map((d, i) =>
userSetTextAlign[i] || d)
index && textTrueAlign.unshift('')
this.textTrueAlign = textTrueAlign
2018-12-08 19:05:46 +08:00
},
2018-12-19 10:33:59 +08:00
getCurrentScrollData (init = false) {
init && (this.currentIndex = 0)
const { currentIndex, rowTrueNum, allRowData, deepClone, carousel } = this
2018-12-08 19:05:46 +08:00
2018-12-19 10:33:59 +08:00
let dealAfterRowData = deepClone(allRowData).map(row => ({ ...row, fade: false }))
if (init && allRowData.length < rowTrueNum) {
this.scrollData = dealAfterRowData
2018-12-12 18:48:00 +08:00
return
}
2018-12-08 19:05:46 +08:00
2018-12-19 10:33:59 +08:00
const needNum = carousel === 'page' ? rowTrueNum * 2 : rowTrueNum + 1
const tempScrollData = dealAfterRowData.slice(currentIndex, currentIndex + needNum)
let stillNum = needNum - tempScrollData.length
2018-12-08 19:05:46 +08:00
2018-12-19 10:33:59 +08:00
while (stillNum) {
tempScrollData.push(...deepClone(dealAfterRowData).slice(0, stillNum))
2018-12-08 19:05:46 +08:00
2018-12-19 10:33:59 +08:00
stillNum = needNum - tempScrollData.length
}
this.scrollData = tempScrollData
2018-12-08 19:05:46 +08:00
2019-01-10 17:31:23 +08:00
const { doFade, waitTime, defaultWaitTime } = this
2018-12-08 19:05:46 +08:00
2019-01-10 19:03:02 +08:00
this.doFadeTimer = setTimeout(doFade, waitTime || defaultWaitTime)
2018-12-08 19:05:46 +08:00
},
doFade () {
2018-12-19 10:33:59 +08:00
const { rowTrueNum, carousel, scrollData, allRowNum, currentIndex } = this
2018-12-08 19:05:46 +08:00
2018-12-19 10:33:59 +08:00
if (carousel === 'page') {
scrollData.forEach((item, i) => i < rowTrueNum && (item.fade = true))
2018-12-08 19:05:46 +08:00
2018-12-19 10:33:59 +08:00
const tempIndex = currentIndex + rowTrueNum
2018-12-08 19:05:46 +08:00
2018-12-19 10:33:59 +08:00
const minus = tempIndex - allRowNum
2018-12-08 19:05:46 +08:00
2018-12-19 10:33:59 +08:00
this.currentIndex = minus >= 0 ? minus : tempIndex
} else {
scrollData[0].fade = true
2018-12-08 19:05:46 +08:00
2018-12-19 10:33:59 +08:00
this.currentIndex = currentIndex + 1 === allRowNum ? 0 : currentIndex + 1
}
const { getCurrentScrollData } = this
2018-12-08 19:05:46 +08:00
2019-01-10 19:03:02 +08:00
this.reAnimationTimer = setTimeout(getCurrentScrollData, 1000)
2018-12-19 10:33:59 +08:00
},
2019-01-10 19:03:02 +08:00
emitClickEvent ({ data, index }, columnIndex) {
this.$emit('click', { data, rowIndex: index, columnIndex: columnIndex + 1 })
2019-01-10 17:31:23 +08:00
},
2018-12-19 10:33:59 +08:00
stopAnimation () {
2019-01-10 19:03:02 +08:00
const { reAnimationTimer, doFadeTimer } = this
2018-12-19 10:33:59 +08:00
2019-01-10 19:03:02 +08:00
reAnimationTimer && clearTimeout(reAnimationTimer)
doFadeTimer && clearTimeout(doFadeTimer)
2018-12-08 19:05:46 +08:00
}
},
2018-12-19 10:33:59 +08:00
mounted () {
2018-12-08 19:05:46 +08:00
const { init } = this
init()
2018-12-19 10:33:59 +08:00
},
destroyed () {
const { stopAnimation } = this
stopAnimation()
2018-12-08 19:05:46 +08:00
}
}
</script>
<style lang="less">
.scroll-board {
2018-12-19 10:33:59 +08:00
position: relative;
2018-12-08 19:05:46 +08:00
width: 100%;
height: 100%;
overflow: hidden;
2018-12-19 10:33:59 +08:00
display: flex;
flex-direction: column;
2019-01-16 16:56:11 +08:00
color: #fff;
2018-12-08 19:05:46 +08:00
2018-12-19 10:33:59 +08:00
.title-container {
height: 35px;
font-size: 14px;
flex-shrink: 0;
display: flex;
flex-direction: row;
2018-12-08 19:05:46 +08:00
}
2018-12-19 10:33:59 +08:00
.title-item {
display: flex;
align-items: center;
&.left {
justify-content: flex-start;
}
&.right {
justify-content: flex-end;
}
&.center {
justify-content: center;
}
2018-12-08 19:05:46 +08:00
}
2018-12-19 10:33:59 +08:00
.row-container {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
2018-12-08 19:05:46 +08:00
}
2018-12-19 10:33:59 +08:00
.row-item {
2018-12-08 19:05:46 +08:00
display: flex;
flex-direction: row;
2018-12-19 10:33:59 +08:00
flex-shrink: 0;
transition: all 0.5s;
2019-01-10 17:31:23 +08:00
overflow: hidden;
2018-12-19 10:33:59 +08:00
&.fade {
height: 0% !important;
2018-12-27 09:21:27 +08:00
color: transparent;
visibility: hidden;
2018-12-19 10:33:59 +08:00
}
}
.row-item-info {
2019-01-10 17:31:23 +08:00
position: relative;
2018-12-19 10:33:59 +08:00
display: flex;
vertical-align: middle;
2018-12-08 19:05:46 +08:00
align-items: center;
2018-12-19 10:33:59 +08:00
vertical-align:middle;
font-size: 13px;
2018-12-08 19:05:46 +08:00
2018-12-19 10:33:59 +08:00
&.left {
text-align: left;
2018-12-08 19:05:46 +08:00
}
2018-12-19 10:33:59 +08:00
&.right {
text-align: right;
2018-12-08 19:05:46 +08:00
}
2018-12-19 10:33:59 +08:00
&.center {
text-align: center;
2018-12-08 19:05:46 +08:00
}
}
2018-12-19 10:33:59 +08:00
.rii-width {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.index-container {
display: flex;
justify-content: center;
}
.index {
font-size: 12px;
width: 16px;
height: 16px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
2018-12-08 19:05:46 +08:00
}
</style>