Html部分:
<template>
<div class="content-right">
<div class="right-item1">
<div class="card-title">公卫当日情况</div>
<div class="lines-content">
<div class="line-item" v-for="(item, index) in rightData.gongweiDailyData" :key="index">
<span>{{ item.describe }}</span>
<span>{{ item.value }}</span>
</div>
</div>
</div>
<div class="right-item2">
<div class="card-title">转诊/检查/检验记录</div>
<div @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave" class="main_container">
<div ref="scrollContainer" class="lines-content scroll_container">
<div
class="line-item scroll_item"
v-for="(item, index) in rightData.rollingData"
:key="index"
>
<span :title="item">{{ index + 1 }}: {{ item }}</span>
</div>
</div>
</div>
</div>
</div>
</template>
TS部分:
<script lang="ts">
import {
onMounted,
onBeforeUnmount,
onUnmounted,
defineComponent,
ref,
nextTick,
reactive,
toRefs
} from 'vue'
export default defineComponent({
name: 'ScreenRight',
components: {},
props: {
rightData: {
type: Object,
default: () => {}
}
},
setup(props) {
const state = reactive({
timer: null as any,
scrollContainer: null as any
})
const handleMouseEnter = () => {
clearTimeout(state.timer)
}
const handleMouseLeave = () => {
start()
}
// 开启定时器
const start = () => {
clearTimeout(state.timer)
// 定时器触发周期
let speed = ref(50)
state.timer = setInterval(ListScroll, speed.value)
}
const ListScroll = () => {
let scrollDom = state.scrollContainer
// 判读组件是否渲染完成
if (scrollDom.offsetHeight == 0) {
scrollDom = state.scrollContainer
} else {
// 如果列表数量过少不进行滚动
if (scrollDom.children.length < 6) {
clearTimeout(state.timer)
return
}
// 组件进行滚动
scrollDom.scrollTop += 1
// 判断是否滚动到底部
if (scrollDom.scrollTop == scrollDom.scrollHeight - scrollDom.clientHeight) {
// 获取组件第一个节点
let first = scrollDom.children[0]
// 删除节点
scrollDom.removeChild(first)
// 将该节点拼接到组件最后
scrollDom.append(first)
}
}
}
onMounted(() => {
// 这里做一个两秒的延迟再滚动,是因为需要等dom元素加载完毕后再执行方法,不然进入页面不会滚动,必须鼠标移入移出才有滚动效果
setTimeout(() => {
start()
}, 2000)
})
onBeforeUnmount(() => {
clearTimeout(state.timer)
})
onUnmounted(() => {
clearTimeout(state.timer)
})
return {
...toRefs(state),
handleMouseEnter,
handleMouseLeave,
start,
ListScroll
}
}
})
</script>
CSS部分:
<style lang="scss" scoped>
.content-right {
width: 30%;
display: flex;
flex-direction: column;
.right-item1 {
width: 100%;
border-radius: 6px;
background-color: rgba(26, 26, 26, 0.4);
// background-image: url('./static/rightTop.png');
background-size: 100% 100%;
position: relative;
}
.right-item2 {
margin-top: 30px;
border-radius: 6px;
background-color: rgba(26, 26, 26, 0.4);
width: 100%;
height: 250px;
// background-image: url('./static/rightBottom.png');
background-size: 100% 100%;
position: relative;
}
}
.card-title {
position: absolute;
top: -11px;
left: 50%;
translate: -50%;
color: #ffffff;
font-size: 0.8vw;
font-weight: 600;
transform: scale(1.5, 1.5);
letter-spacing: 2px;
text-shadow: 0 0 4px #a1a1a1, 0 0 8px #010869;
}
.lines-content {
padding: 20px;
padding-top: 30px;
font-size: 14px;
color: #e0e0e0;
.line-item {
display: flex;
flex-direction: row;
justify-content: space-between;
line-height: 40px;
}
}
.main_container {
height: 240px;
padding-top: 20px;
.scroll_container {
width: 100%;
height: 100%;
overflow: hidden;
.scroll_item {
width: 100%;
// line-height: 32px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
span {
cursor: position;
}
}
}
}
</style>