Files
sgxt_web/src/views/home/model/experience.vue
2025-10-26 12:25:50 +08:00

193 lines
4.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>