vue -(滚动播放-全屏展示)
vue可视化
git地址:https://gitee.com/HuaWang400/jiajuxiaoshou
转载自:https://juejin.cn/post/6931189766109003783

滚动播报

公共组件-路由组件
<template> <div class="scroll"> <div class="scroll-header" :style="{ height : headerConfig.headerHeight + 'px', background: headerConfig.headerBackground, }"> <div class="scroll-header-item" v-for="(item, index) in headerConfig.headerItems" :key = "'scroll-header-item' + index" :style="{ width: averageWidth + 'px', ... headerConfig.headerStyle[index] }"> {{item}}</div> </div> <div class="scroll-content" ref="scrollContent"> <div v-for="(item, index) in rowsData" :key = "item.index" :style = "{ height: rowHeights[index] + 'px', background: item.index % 2 === 0 ? rowBackground[0] : rowBackground[1] }" class="scroll-content-li"> <div v-for="( k, i ) in Object.keys(item.data)" :key = "'scroll-content-li' + i" class="scroll-content-li-item" :style="{ width: headerConfig.headerStyle[i].width ? headerConfig.headerStyle[i].width : averageWidth + 'px', }">{{item.data[k]}}</div> </div> </div> </div> </template> <script> export default { name: 'scroll', props: { header: { type: Object, required: true }, rows: { type: Array, required: true }, capacity: { type: Number, required: true }, rowBackground: { type: Array, default: function () { return ['hsl(207deg 84% 51% / 8%)', 'transparent'] } }, duration: { type: Number, default: 3000 } }, data () { return { headerConfig: null, averageWidth: 0, rowHeight: 0, currentIndex: 0, rowsx: null, rowsData: null, step: 1, rowHeights: new Array(this.rows.length).fill(0) } }, watch: { rows: { handler (newValue, oldValue) { this.handleRowData() const index = this.currentIndex > 0 ? this.currentIndex - 1 : this.currentIndex const temp = this.rowsx.slice(index) temp.push(...this.rowsx.slice(0, index)) this.rowsData = temp clearTimeout(this.timer) this.timer = setTimeout(() => { this.animation() }, this.duration) }, deep: true } }, methods: { handleRowData () { let temp = this.rows.slice() if (this.rows.length > this.capacity) { temp = this.rows.slice().concat(this.rows.slice()) } this.rowsx = temp.map((item, index) => { return { data: item, index: index } }) this.rowsData = this.rowsx.slice() }, setConfig () { const headerConfigDefault = { headerItems: [], headerBackground: 'transparent', headerHeight: 60, headerStyle: [] } this.headerConfig = Object.assign(headerConfigDefault, this.header) this.handleRowData() }, setHeaderWidth () { const width = this.$el.clientWidth let fixedWidth = 0 let n = 0 this.headerConfig.headerStyle.forEach(item => { if (item.width) { fixedWidth += parseInt(item.width) n++ } }) this.averageWidth = (width - fixedWidth) / (this.header.headerItems.length - n) }, animation () { clearTimeout(this.timer) const len = this.rowsx.length if (len <= this.capacity) return const temp = this.rowsx.slice(this.currentIndex) temp.push(...this.rowsx.slice(0, this.currentIndex)) this.rowHeights = new Array(len).fill(this.rowHeight) this.rowHeights.splice(0, this.step, ...new Array(this.step).fill(0)) this.rowsData = temp this.currentIndex += this.step const isLast = this.currentIndex - len if (isLast >= 0) this.currentIndex = isLast this.timer = setTimeout(() => { this.animation() }, this.duration) }, setContentHeight () { const height = this.$el.clientHeight const h = height - this.headerConfig.headerHeight this.$refs.scrollContent.style.height = h + 'px' const min = Math.min(this.rows.length, this.capacity) this.rowHeight = h / min this.rowHeights = new Array(min).fill(this.rowHeight) } }, created () { if (!this.header.headerItems || this.header.headerItems.length === 0) return this.setConfig() this.$nextTick(() => { this.setHeaderWidth() this.setContentHeight() this.timer = setTimeout(() => { this.animation() }, this.duration) }) } } </script> <style lang="less" scoped> .scroll{ height: 100%; width: 100%; text-align: center; &-header{ display: flex; align-items: center; &-item{ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } } &-content{ overflow: hidden; &-li{ display: flex; align-items: center; overflow: hidden; transition: all 0.3s linear; &-item{ display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:2; overflow:hidden; padding:0 10px; } } } } </style>
<template>
<div class="star-product">
<div class="title">明星产品销售概况</div>
<div class="list">
<scroll
:header="header"
:rows="list"
:duration="duration"
:capacity="6"
></scroll>
</div>
</div>
</template>
<script>
import Scroll from "@/components/Common/Scroll";
export default {
components: {
Scroll,
},
data() {
return {
starProduct: [
{
name: "A品牌木门",
sales: 92090,
orders: 51,
},
{
name: "B品牌沙发",
sales: 602090,
orders: 107,
},
{
name: "C品牌衣柜",
sales: 802090,
orders: 94,
},
{
name: "D品牌木门",
sales: 92090,
orders: 51,
},
{
name: "E品牌沙发",
sales: 602090,
orders: 107,
},
{
name: "F品牌木门",
sales: 92090,
orders: 51,
},
{
name: "G品牌木门",
// sales: 92090,
// orders: 51,
},
// {
// name: "H品牌沙发",
// sales: 602090,
// orders: 107,
// },
],
header: {
headerItems: ["产品", "销售额", "订单量",],
headerHeight: 140,
headerStyle: [
{
fontSize: "45px",
},
{
width: "260px",
fontSize: "45px",
},
{
width: "260px",
fontSize: "45px",
},
],
},
rowBg: ["red", "green"],
duration: 3000,
};
},
computed: {
list() {
return this.starProduct;
},
},
};
</script>
<style lang="less" scoped>
.star-product {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
.title {
height: 100px;
font-size: 40px;
font-weight: bold;
}
.list {
flex: 1;
width: 100%;
font-size: 36px;
}
}
</style>
全屏/退出
<template> <div class="display-header"> <span class="sub">数据更新于:{{ time }}</span> <span class="title">2020秋季家具交易会实时销售数据可视化平台</span> <span class="sub full-screen" @click="toggleScreen">{{ operationText }}</span> </div> </template> <script> let timer export default { data () { return { isFullScreen: false } }, computed: { operationText () { return this.isFullScreen ? '退出' : '全屏' }, time () { const t = this.$store.state.updateTime return `${t.toLocaleDateString()} ${t.toLocaleTimeString()}` } }, methods: { toggleScreen () { const main = document.body if (this.isFullScreen) { if (document.exitFullscreen) { document.exitFullscreen() } else if (document.mozCancelFullScreen) { document.mozCancelFullScreen() } else if (document.webkitCancelFullScreen) { document.webkitCancelFullScreen() } else if (document.msExitFullscreen) { document.msExitFullscreen() } } else { if (main.requestFullscreen) { main.requestFullscreen() } else if (main.mozRequestFullScreen) { main.mozRequestFullScreen() } else if (main.webkitRequestFullScreen) { main.webkitRequestFullScreen() } else if (main.msRequestFullscreen) { main.msRequestFullscreen() } } }, changeFullScreenStatus () { this.isFullScreen = !this.isFullScreen } }, mounted () { if (document.body.requestFullscreen) { document.addEventListener('fullscreenchange', this.changeFullScreenStatus) } else if (document.body.msRequestFullscreen) { document.addEventListener('MSFullscreenChange', this.changeFullScreenStatus) } }, destroyed () { clearInterval(timer) if (document.body.requestFullscreen) { document.removeEventListener('fullscreenchange', this.changeFullScreenStatus) } else if (document.body.msRequestFullscreen) { document.removeEventListener('MSFullscreenChange', this.changeFullScreenStatus) } } } </script> <style lang="scss" scoped> .display-header{ height: 100%; display: flex; align-items: center; justify-content: space-between; padding: 0 30px; .title{ font-size: 60px; color: #fff; letter-spacing: .1em; } .sub{ width: 1000px; color: rgba(255,255,255,.3); } .full-screen{ cursor: pointer; position: relative; text-align: right; &:before{ content: ''; position: absolute; top: -20px; bottom: -20px; left: -20px; right: -20px; } } } </style>
作者:华王
博客:https://www.cnblogs.com/huahuawang/
浙公网安备 33010602011771号