193 lines
4.5 KiB
Vue
193 lines
4.5 KiB
Vue
<template>
|
||
<div class="comom-title" @click="chooseForumPost">
|
||
<span class="title">情报论坛</span>
|
||
</div>
|
||
<div class="comom-cnt" style="height: 300px;">
|
||
<div class="zdryBox">
|
||
<div class="carousel-container"
|
||
@mouseenter="pauseCarousel"
|
||
@mouseleave="startCarousel">
|
||
<ul class="ryBox" ref="carouselList">
|
||
<li v-for="item in displayList" :key="item.id" @click="chooseItem(item)">
|
||
<div>{{ item.title }}</div>
|
||
<div class="meta-info">{{ item.time }}{{ item.fbrxm }}</div>
|
||
<div>{{ item.content }}</div>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { tbGsxtXxltSelectPage } from '@/api/tbGsxtXxltHf'
|
||
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue';
|
||
import {useRouter} from 'vue-router'
|
||
const router = useRouter()
|
||
|
||
// 数据相关
|
||
const personList = ref([]);
|
||
const displayList = ref([]); // 用于显示的数据列表
|
||
const loading = ref(false);
|
||
|
||
// 轮播相关
|
||
const carouselList = ref(null);
|
||
const scrollTimer = ref(null);
|
||
const scrollSpeed = ref(3000); // 滚动间隔时间(ms)
|
||
const itemHeight = ref(106); // 每个item的高度(px)
|
||
const currentIndex = ref(0);
|
||
|
||
// 获取数据
|
||
const getList = () => {
|
||
loading.value = true;
|
||
tbGsxtXxltSelectPage({ pageSize: 10, pageCurrent: 1 }).then(res => {
|
||
loading.value = false;
|
||
personList.value = res.records || [];
|
||
// 复制一份数据到displayList,实现无缝滚动效果
|
||
displayList.value = [...personList.value, ...personList.value];
|
||
}).catch(() => {
|
||
loading.value = false;
|
||
})
|
||
};
|
||
|
||
// 开始轮播
|
||
const startCarousel = () => {
|
||
if (scrollTimer.value) return;
|
||
|
||
scrollTimer.value = setInterval(() => {
|
||
scrollToNext();
|
||
}, scrollSpeed.value);
|
||
};
|
||
|
||
// 暂停轮播
|
||
const pauseCarousel = () => {
|
||
if (scrollTimer.value) {
|
||
clearInterval(scrollTimer.value);
|
||
scrollTimer.value = null;
|
||
}
|
||
};
|
||
|
||
// 滚动到下一项
|
||
const scrollToNext = () => {
|
||
if (!carouselList.value || personList.value.length === 0) return;
|
||
|
||
currentIndex.value++;
|
||
// 实现平滑滚动
|
||
const scrollHeight = currentIndex.value * itemHeight.value;
|
||
|
||
carouselList.value.style.transition = 'transform 0.5s ease-out';
|
||
carouselList.value.style.transform = `translateY(-${scrollHeight}px)`;
|
||
|
||
// 当滚动到复制的数据部分时,重置位置实现无缝滚动
|
||
if (currentIndex.value >= personList.value.length) {
|
||
setTimeout(() => {
|
||
currentIndex.value = 0;
|
||
carouselList.value.style.transition = 'none';
|
||
carouselList.value.style.transform = 'translateY(0)';
|
||
}, 500);
|
||
}
|
||
};
|
||
|
||
// 点击项
|
||
const chooseItem = (item) => {
|
||
pauseCarousel(); // 点击时暂停轮播
|
||
router.push({
|
||
path: '/forumPost',
|
||
query: { id: item.id }
|
||
})
|
||
};
|
||
|
||
// 添加跳转
|
||
const chooseForumPost = () => {
|
||
pauseCarousel(); // 点击时暂停轮播
|
||
router.push({ path: '/forumPost' })
|
||
};
|
||
|
||
// 生命周期
|
||
onMounted(() => {
|
||
getList();
|
||
// 数据加载后开始轮播
|
||
setTimeout(() => {
|
||
startCarousel();
|
||
}, 1000);
|
||
});
|
||
|
||
// 组件卸载前清除定时器
|
||
onBeforeUnmount(() => {
|
||
pauseCarousel();
|
||
});
|
||
</script>
|
||
|
||
<style>
|
||
.el-loading-mask {
|
||
background: rgba(0, 0, 0, 0.5);
|
||
}
|
||
</style>
|
||
|
||
<style lang="scss" scoped>
|
||
@import "@/assets/css/homeScreen.scss";
|
||
|
||
.zdryBox {
|
||
height: 100%;
|
||
position: relative;
|
||
overflow: hidden;
|
||
|
||
.carousel-container {
|
||
height: 100%;
|
||
overflow: hidden;
|
||
position: relative;
|
||
}
|
||
|
||
.ryBox {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
margin: 0;
|
||
padding: 0;
|
||
list-style: none;
|
||
|
||
li {
|
||
padding: 12px;
|
||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||
transition: background-color 0.3s;
|
||
cursor: pointer;
|
||
|
||
&:hover {
|
||
background-color: rgba(20, 107, 190, 0.2);
|
||
}
|
||
|
||
> div:first-child {
|
||
font-weight: bold;
|
||
color: #fff;
|
||
margin-bottom: 8px;
|
||
font-size: 14px;
|
||
/* 标题限制1行,超出用省略号 */
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.meta-info {
|
||
text-align: right;
|
||
color: #83bff6;
|
||
font-size: 12px;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
> div:last-child {
|
||
color: rgba(255, 255, 255, 0.8);
|
||
font-size: 13px;
|
||
line-height: 1.6;
|
||
/* 内容限制3行,超出用省略号 */
|
||
display: -webkit-box;
|
||
-webkit-line-clamp: 3;
|
||
-webkit-box-orient: vertical;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|