completed

This commit is contained in:
jiaming 2018-12-19 10:33:59 +08:00
parent 47a70c4c4c
commit 9cc5cc3870
3 changed files with 392 additions and 82 deletions

View File

@ -1,16 +1,41 @@
<template> <template>
<div class="scroll-board"> <div class="scroll-board" :ref="ref">
<loading v-if="!data" /> <loading v-if="!data" />
<template v-else> <template v-else>
<div :class="`scroll-item ${item.index % 2 === 0 ? 'deep' : 'light'} ${fade && index === 0 && 'fade'}`" <div class="title-container"
v-for="(item, index) in scrollData" v-if="titleData"
:key="item.title + index" :style="`background-color:${titleTrueBG};`">
:style="`height: ${100 / (data.showItemNum || 5)}%`"> <div :class="`title-item ${textTrueAlign[ti]}`"
<div class="index">{{ item.index }}</div> v-for="(title, ti) in titleData" :key="title + ti"
<div class="title">{{ item.title }}</div> :style="`width: ${columnTrueWidth[ti]};`">
<div class="info">{{ item.info }}</div> {{ 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"
:key="info">
<div :class="`rii-width ${ii === 0 && index && 'index-container'}`" :style="`width: ${columnTrueWidth[ii]};`">
<template v-if="ii === 0 && index">
<div class="index" :style="`background-color:${titleTrueBG};`">{{ info }}</div>
</template>
<template v-else>
{{ info }}
</template>
</div>
</div>
</div>
</div> </div>
</template> </template>
</div> </div>
@ -19,138 +44,318 @@
<script> <script>
export default { export default {
name: 'scroll-board', name: 'scroll-board',
props: ['data'], props: ['data', 'index', 'rowNum', 'titBG', 'oddBG', 'evenBG', 'columnWidth', 'textAlign', 'carousel'],
data () { data () {
return { return {
dealAfterData: [], ref: `scroll-board-${(new Date()).getTime()}`,
container: '',
containerWH: [],
fade: false, defaultRowNum: 5,
scrollData: [], defaultTitleBG: '#00BAFF',
currentTopIndex: 0, defaultOddBG: '#003B51',
defaultEvenBG: '#0A2732',
autoScrollHandler: '' waitTime: 2000,
rowTrueNum: '',
rowHeight: '',
titleTrueBG: '',
oddTrueBG: '',
evenTrueBG: '',
columnTrueWidth: [],
textTrueAlign: [],
currentIndex: 0,
allRowNum: 0,
allColumnNum: 0,
titleData: '',
allRowData: [],
scrollData: []
} }
}, },
watch: { watch: {
data () { data () {
const { init, autoScrollHandler } = this // const { init, autoScrollHandler } = this
this.fade = false // this.fade = false
this.currentTopIndex = 0 // this.currentTopIndex = 0
autoScrollHandler && clearTimeout(autoScrollHandler) // autoScrollHandler && clearTimeout(autoScrollHandler)
init() // init()
} }
}, },
methods: { methods: {
init () { init () {
const { data, getDealAfterData, getCurrentScrollData } = this const { data, initDom, dealData, calcConfig, getCurrentScrollData } = this
initDom()
if (!data) return if (!data) return
getDealAfterData() dealData()
getCurrentScrollData() calcConfig()
getCurrentScrollData(true)
}, },
getDealAfterData () { initDom () {
const { data: { data } } = this const { $refs, ref } = this
this.dealAfterData = data.map(({ title, info }, i) => ({ index: i + 1, title, info })) const container = this.container = $refs[ref]
this.containerWH[0] = container.clientWidth
this.containerWH[1] = container.clientHeight
}, },
getCurrentScrollData () { dealData () {
const { dealAfterData, data: { showItemNum }, currentTopIndex, doFade } = this const { data: { data, title }, index, deepClone } = this
if (dealAfterData.length < showItemNum) { if (title) (this.titleData = index ? ['', ...title] : [...title])
this.scrollData = dealAfterData
this.allRowData = deepClone(data).map((row, i) =>
({ 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 () {
const { data: { data }, index } = this
this.allRowNum = data.length
this.allColumnNum = data[0].length + (index ? 1 : 0)
},
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 || []
const textTrueAlign = new Array(allColumnNum).fill('left').map((d, i) =>
userSetTextAlign[i] || d)
index && textTrueAlign.unshift('')
this.textTrueAlign = textTrueAlign
},
getCurrentScrollData (init = false) {
init && (this.currentIndex = 0)
const { currentIndex, rowTrueNum, allRowData, deepClone, carousel } = this
let dealAfterRowData = deepClone(allRowData).map(row => ({ ...row, fade: false }))
if (init && allRowData.length < rowTrueNum) {
this.scrollData = dealAfterRowData
return return
} }
const tempArray = dealAfterData.slice(currentTopIndex, currentTopIndex + showItemNum + 1) const needNum = carousel === 'page' ? rowTrueNum * 2 : rowTrueNum + 1
const appendNum = showItemNum - tempArray.length + 1 const tempScrollData = dealAfterRowData.slice(currentIndex, currentIndex + needNum)
tempArray.push(...dealAfterData.slice(0, appendNum)) let stillNum = needNum - tempScrollData.length
this.scrollData = tempArray while (stillNum) {
tempScrollData.push(...deepClone(dealAfterRowData).slice(0, stillNum))
this.autoScrollHandler = setTimeout(doFade, 1500) stillNum = needNum - tempScrollData.length
}
this.scrollData = tempScrollData
const { doFade, waitTime } = this
setTimeout(doFade, waitTime)
}, },
doFade () { doFade () {
const { reGetCurrentScrollData } = this const { rowTrueNum, carousel, scrollData, allRowNum, currentIndex } = this
this.fade = true if (carousel === 'page') {
scrollData.forEach((item, i) => i < rowTrueNum && (item.fade = true))
this.autoScrollHandler = setTimeout(reGetCurrentScrollData, 1500) const tempIndex = currentIndex + rowTrueNum
const minus = tempIndex - allRowNum
this.currentIndex = minus >= 0 ? minus : tempIndex
} else {
scrollData[0].fade = true
this.currentIndex = currentIndex + 1 === allRowNum ? 0 : currentIndex + 1
}
const { getCurrentScrollData } = this
this.animationHandler = setTimeout(getCurrentScrollData, 1000)
}, },
reGetCurrentScrollData () { stopAnimation () {
const { getCurrentScrollData, dealAfterData, currentTopIndex } = this const { animationHandler } = this
this.fade = false clearTimeout(animationHandler)
const tempNextIndex = currentTopIndex + 1
this.currentTopIndex = (tempNextIndex === dealAfterData.length ? 0 : tempNextIndex)
getCurrentScrollData()
} }
}, },
created () { mounted () {
const { init } = this const { init } = this
init() init()
},
destroyed () {
const { stopAnimation } = this
stopAnimation()
} }
} }
</script> </script>
<style lang="less"> <style lang="less">
.scroll-board { .scroll-board {
position: relative;
width: 100%; width: 100%;
height: 100%; height: 100%;
overflow: hidden; overflow: hidden;
display: flex;
flex-direction: column;
.fade { .title-container {
height: 0% !important; height: 35px;
} font-size: 14px;
flex-shrink: 0;
.deep {
background-color: rgba(9, 37, 50, 0.4);
}
.light {
background-color: rgba(10, 32, 50, 0.3);
}
.scroll-item {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center;
transition: all 1s;
overflow: hidden;
.index {
width: 20px;
height: 20px;
border-radius: 50%;
text-align: center;
line-height: 20px;
font-size: 14px;
background-color: #00baff;
margin-left: 10px;
} }
.title { .title-item {
font-size: 12px; display: flex;
width: 25%; align-items: center;
&.left {
justify-content: flex-start;
}
&.right {
justify-content: flex-end;
}
&.center {
justify-content: center;
}
}
.row-container {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
.row-item {
display: flex;
flex-direction: row;
flex-shrink: 0;
transition: all 0.5s;
&.fade {
height: 0% !important;
}
}
.row-item-info {
display: flex;
vertical-align: middle;
align-items: center;
vertical-align:middle;
font-size: 13px;
&.left {
text-align: left;
}
&.right {
text-align: right;
}
&.center {
text-align: center;
}
}
.rii-width {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
.info { .index-container {
font-size: 14px; display: flex;
justify-content: center;
} }
.index {
font-size: 12px;
width: 16px;
height: 16px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
} }
} }
</style> </style>

View File

@ -42,6 +42,10 @@ export default {
{ {
title: 'Other', title: 'Other',
routerName: 'other' routerName: 'other'
},
{
title: 'Show',
routerName: 'show'
} }
] ]
} }

View File

@ -1,5 +1,77 @@
<template> <template>
<div id="other"> <div id="other">
<border-box-7 class="other-item">
<div class="component">
<scroll-board :index="true" :data="scrollBoardData1" :columnWidth="[50, 50, 50]" :textAlign="['center', 'center']" />
</div>
<div class="config-info">
<div class="title">Water-Level-Pond</div>
<highlight-code>
&lt;scroll-board :data="data" :index="true" :columnWidth="columnWidth" :textAlign="textAlign" /&gt;
</highlight-code>
<highlight-code>
data: {
data: [ //
['张三', '男', '这里是地址'],
['李四', '女', '这里是地址'],
['王五', '男', '这里是地址'],
['赵六', '女', '这里是地址'],
['钱七', '男', '这里是地址'],
['孙八', '女', '这里是地址'],
['杨九', '男', '这里是地址'],
['吴十', '女', '这里是地址']
]
}
//
columnWidth: [50, 50, 50]
//
textAlign: ['center', 'center']
// index
// rowNum
// oddBG
// evenBG
// titBG
// carousel page
</highlight-code>
</div>
</border-box-7>
<border-box-7 class="other-item">
<div class="component">
<scroll-board :data="scrollBoardData2" carousel="page" :columnWidth="[50, 50]" :textAlign="['center', 'center']" />
</div>
<div class="config-info">
<div class="title">Water-Level-Pond</div>
<highlight-code>
&lt;scroll-board :data="data" carousel="page" :columnWidth="columnWidth" :textAlign="textAlign" /&gt;
</highlight-code>
<highlight-code>
data: {
data: [
['张三', '男', '这里是地址'],
['李四', '女', '这里是地址'],
['王五', '男', '这里是地址'],
['赵六', '女', '这里是地址'],
['钱七', '男', '这里是地址'],
['孙八', '女', '这里是地址'],
['杨九', '男', '这里是地址'],
['吴十', '女', '这里是地址']
],
//
title: ['姓名', '性别', '地址']
}
columnWidth: [50, 50]
textAlign: ['center', 'center']
</highlight-code>
</div>
</border-box-7>
<border-box-7 class="other-item"> <border-box-7 class="other-item">
<div class="component"> <div class="component">
<water-level-pond :level="[60, 40]" /> <water-level-pond :level="[60, 40]" />
@ -94,15 +166,39 @@
export default { export default {
name: 'Other', name: 'Other',
data () { data () {
return {} return {
scrollBoardData1: {
data: [
['张三', '男', '这里是地址这里是地址这里是地址这里是地址'],
['李四', '女', '这里是地址这里是地址这里是地址这里是地址'],
['王五', '男', '这里是地址这里是地址这里是地址这里是地址'],
['赵六', '女', '这里是地址这里是地址这里是地址这里是地址'],
['钱七', '男', '这里是地址这里是地址这里是地址这里是地址'],
['孙八', '女', '这里是地址这里是地址这里是地址这里是地址'],
['杨九', '男', '这里是地址这里是地址这里是地址这里是地址'],
['吴十', '女', '这里是地址这里是地址这里是地址这里是地址']
]
},
scrollBoardData2: {
data: [
['张三', '男', '这里是地址这里是地址这里是地址这里是地址'],
['李四', '女', '这里是地址这里是地址这里是地址这里是地址'],
['王五', '男', '这里是地址这里是地址这里是地址这里是地址'],
['赵六', '女', '这里是地址这里是地址这里是地址这里是地址'],
['钱七', '男', '这里是地址这里是地址这里是地址这里是地址'],
['孙八', '女', '这里是地址这里是地址这里是地址这里是地址'],
['杨九', '男', '这里是地址这里是地址这里是地址这里是地址'],
['吴十', '女', '这里是地址这里是地址这里是地址这里是地址']
],
title: ['姓名', '性别', '地址']
}
}
} }
} }
</script> </script>
<style lang="less"> <style lang="less">
#other { #other {
width: 100%;
height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -135,6 +231,11 @@ export default {
} }
} }
.scroll-board {
width: 350px;
height: 200px;
}
.water-level-pond { .water-level-pond {
width: 150px; width: 150px;
height: 200px; height: 200px;