需求人员表示,超过高度的表格内容需要滚动展示,所以效果图如下:
自定义列表样式,主要是通过flex布局,控制 类th 与 类td 的宽度保持一致,标签结构还是参考了table的结构,由thead与tbody包裹tr再包裹最小单元th,td,但是自定义的列表在样式修改、结构调整上会更加灵活。
.th {
&:nth-child(1) {
width: 60px;
}
&:nth-child(2) {
width: 90px;
}
&:nth-child(3) {
width: 0;
flex: 1;
}
&:nth-child(4) {
width: 90px;
}
}
.td {
&:nth-child(1) {
width: 60px;
}
&:nth-child(2) {
width: 90px;
}
&:nth-child(3) {
width: 0;
flex: 1;
}
&:nth-child(4) {
width: 90px;
}
}
this.stopAutoScroll() 与 this.startAutoScroll() 都是AI生成的JS代码修改而来
在 mounted() 中通过循环创造20条数据的列表,再通过 $nextTick ,当列表数量(length)超过5时,调用startAutoScroll方法进行自动滚动,在该方法之前调用stopAutoScroll是为了防抖节流。如果有主要思路想法,可以借助通义千问等AI工具进行JS代码的快速生成,节约时间。
mounted() {
for (let i = 0; i < 20; i++) {
let obj = {
id: 'tableData00' + i,
td1: i + 1,
td2: 'td2',
td3: i % 3 == 0 ? '测试测试测试' : i % 3 == 1 ? '测试测试' : '测试',
td4: '99'
}
this.tableData.push(obj)
}
this.$nextTick(function () {
// 当列表超过5条,自动滚动,可自行修改
if (this.tableData.length > 5) {
// 自动滚动
this.stopAutoScroll();
this.startAutoScroll();
}
})
},
【完整代码】
<template>
<div class="cus-list-wrap">
<div class="thead">
<div class="tr">
<div class="th">th1</div>
<div class="th">th2</div>
<div class="th">th3</div>
<div class="th">th4</div>
</div>
</div>
<div class="tbody hit1" ref="scrollContainer">
<div class="tr" v-for="item in tableData" :key="item.id">
<div class="td">
{{ item.td1 }}
</div>
<div class="td">
{{ item.td2 }}
</div>
<div class="td">
{{ item.td3 }}
</div>
<div class="td">
{{ item.td4 }}
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
tableData: [],
isScrollingDown: true,
scrollAnimationFrameId: null,
isAutoScrollRunning: false,
}
},
mounted() {
for (let i = 0; i < 20; i++) {
let obj = {
id: 'tableData00' + i,
td1: i + 1,
td2: 'td2',
td3: i % 3 == 0 ? '测试测试测试' : i % 3 == 1 ? '测试测试' : '测试',
td4: '99'
}
this.tableData.push(obj)
}
this.$nextTick(function () {
// 当列表超过5条,自动滚动,可自行修改
if (this.tableData.length > 5) {
// 自动滚动
this.stopAutoScroll();
this.startAutoScroll();
}
})
},
methods: {
// 自动滚动
startAutoScroll() {
if (this.isAutoScrollRunning) return;
this.isAutoScrollRunning = true;
const scrollContainer = this.$refs.scrollContainer;
let scrollSpeed = 1; // 控制滚动速度
const autoScroll = () => {
if (!this.isAutoScrollRunning) return;
if (this.isScrollingDown) {
scrollContainer.scrollTop += scrollSpeed;
if (scrollContainer.scrollTop + scrollContainer.clientHeight >= scrollContainer.scrollHeight) {
// 到达底部后切换方向,并设置一个小延时模拟“回到顶部”
this.isScrollingDown = false;
scrollContainer.scrollTop = 0;
setTimeout(() => {
this.isScrollingDown = true;
}, 300); // 延迟时间可以根据需要调整
}
} else {
scrollContainer.scrollTop -= scrollSpeed;
if (scrollContainer.scrollTop <= 0) {
this.isScrollingDown = true;
}
}
this.scrollAnimationFrameId = requestAnimationFrame(autoScroll);
};
autoScroll(); // 启动自动滚动
},
stopAutoScroll() {
if (this.scrollAnimationFrameId !== null) {
cancelAnimationFrame(this.scrollAnimationFrameId);
this.isAutoScrollRunning = false;
}
},
},
beforeDestroy() {
// 清除定时器以避免内存泄漏
this.stopAutoScroll();
},
}
</script>
<style lang="less" scoped>
.cus-list-wrap {
margin: 0 16px;
padding-top: 4px;
}
.hit1 {
overflow-x: hidden;
overflow-y: auto;
height: 400px;
}
.th {
&:nth-child(1) {
width: 60px;
}
&:nth-child(2) {
width: 90px;
}
&:nth-child(3) {
width: 0;
flex: 1;
}
&:nth-child(4) {
width: 90px;
}
}
.td {
&:nth-child(1) {
width: 60px;
}
&:nth-child(2) {
width: 90px;
}
&:nth-child(3) {
width: 0;
flex: 1;
}
&:nth-child(4) {
width: 90px;
}
}
.thead {
.tr {
display: flex;
align-items: center;
height: 30px;
}
.th {
text-align: center;
font-size: 14px;
color: #666;
}
}
.tbody {
.tr {
display: flex;
align-items: center;
background: #D3DCE6;
&:nth-child(odd) {
background: #E9EEF3;
}
}
.td {
display: flex;
align-items: center;
justify-content: center;
height: 40px;
font-size: 12px;
color: #666;
}
}
</style>