Vue3+elementPlus 搞一个列表滚动的功能吧

先看展示:

消息滚动

再看代码

	<template>
	  <div
	    class="scroll-container"
	    @mouseenter="pauseScroll"
	    @mouseleave="resumeScroll"
	  >
	    <el-table
	      :data="displayData"
	      :height="tableHeight"
	      style="width: 100%"
	      :row-class-name="tableRowClassName"
	      border
	    >
	      <el-table-column prop="type" label="消息类型" />
	      <el-table-column prop="content" label="消息内容" />
	      <el-table-column prop="timestamp" label="创建时间" />
	    </el-table>
	  </div>
	</template>
	
	<script setup>
	import { ref, computed, onMounted, onBeforeUnmount } from "vue";
	//这里就是个生成消息数据的函数
	function generateRandomMessage() {
	  // 消息类型配置
	  const messageTypes = [
	    {
	      type: "system",
	      templates: [
	        "系统维护通知:服务将于今晚23:00进行升级",
	        "新功能模块已上线,请前往体验",
	        "安全提示:检测到异常登录,请立即修改密码",
	      ],
	    },
	    {
	      type: "user",
	      templates: [
	        "用户@{{username}} 加入了频道",
	        "{{username}} 发送了新的文件:{{filename}}",
	        "{{username}} 提到了你:{{content}}",
	      ],
	    },
	    {
	      type: "warning",
	      templates: [
	        "警告:存储空间不足,请清理文件",
	        "您的账号存在安全风险,请进行身份验证",
	        "检测到异常操作,已暂时冻结账号",
	      ],
	    },
	    {
	      type: "promotion",
	      templates: [
	        "限时优惠:专业版5折起",
	        "邀请好友得积分,100积分=10元",
	        "新用户专享礼包已发放至账户",
	      ],
	    },
	  ];
	
	  // 随机选择消息类型
	  const randomType =
	    messageTypes[Math.floor(Math.random() * messageTypes.length)];
	
	  // 生成随机数据
	  const randomData = {
	    username: ["Alice", "Bob", "Charlie", "David"][
	      Math.floor(Math.random() * 4)
	    ],
	    filename: ["report.pdf", "design.png", "data.csv"][
	      Math.floor(Math.random() * 3)
	    ],
	    content: ["这个项目需要你的帮助", "请查看最新文档", "会议时间需要调整"][
	      Math.floor(Math.random() * 3)
	    ],
	  };
	
	  // 选择随机模板并替换变量
	  const template =
	    randomType.templates[
	      Math.floor(Math.random() * randomType.templates.length)
	    ];
	  let messageContent = template.replace(
	    /{{(\w+)}}/g,
	    (_, key) => randomData[key] || ""
	  );
	
	  // 生成完整消息对象
	  return {
	    id: Date.now(), // 使用时间戳作为唯一ID
	    type: randomType.type,
	    content: messageContent,
	    timestamp: new Date().toISOString(),
	    sender: randomType.type === "user" ? randomData.username : "System",
	  };
	}
	
	// 创建原始数据
	const originalData = ref([]);
	for (let i = 0; i < 30; i++) {
	  originalData.value.push(generateRandomMessage());
	}
	
	// 表格显示数据(双倍数据用于循环)
	const displayData = computed(() => [
	  ...originalData.value,
	  ...originalData.value, // 克隆一份数据实现无缝衔接 还需要注意的是,一份数据的总高度要大于表格展示的高度,不然会卡顿
	]);
	
	// 表格高度
	const tableHeight = ref(500); 
	// 滚动控制标志
	const isPaused = ref(false);
	// 滚动定时器
	let scrollInterval = null;
	// 滚动位置偏移量
	let scrollOffset = 0;
	
	// 自动滚动函数
	const autoScroll = () => {
	  scrollInterval = setInterval(() => {
	    if (!isPaused.value) {
	      const tableBody = document.querySelector(".el-scrollbar__wrap"); //看好需要获取DOM的类名
	      if (tableBody) {
	        // 更新滚动位置
	        scrollOffset += 1;
	        tableBody.scrollTop = scrollOffset;
	        // 当滚动到第二份数据末尾时,瞬间跳回第一份数据开头 这里就是让他循环滚动
	        if (scrollOffset >= tableBody.scrollHeight / 2) {
	          requestAnimationFrame(() => {
	            tableBody.scrollTop = 0;
	            scrollOffset = 0;
	          });
	        }
	      }
	    }
	  }, 20);
	};
	const tableRowClassName = ({ row, rowIndex }) => {
	  if (row.type === "system") {
	    return "system-row";
	  }
	  if (row.type === "warning") {
	    return "warning-row";
	  }
	};
	// 暂停滚动
	const pauseScroll = () => {
	  isPaused.value = true;
	};
	
	// 恢复滚动
	const resumeScroll = () => {
	  isPaused.value = false;
	};
	
	// 生命周期钩子
	onMounted(() => {
	  autoScroll();
	});
	
	onBeforeUnmount(() => {
	  clearInterval(scrollInterval);
	});
	</script>
	
	<style scoped lang="scss">
	.scroll-container {
	  height: 500px;
	}
	/* 穿透样式 */
	::v-deep(.el-table) {
	  .system-row {
	    --el-table-tr-bg-color: var(--el-color-success-light-9);
	  }
	}
	</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值