【Auto-Scroll-List 组件设计与实现分析】

Auto-Scroll-List 组件设计与实现分析

gitee代码仓库
https://gitee.com/chennaiyuan/dayup-record/tree/master/%E4%B8%80%E4%BA%9B%E7%BB%84%E4%BB%B6/auto-scroll-list

1. 组件概述

我们封装的 AutoScrollList 是一个自动滚动列表组件,主要用于展示需要自动循环滚动的数据项,如通知、告警、任务等信息。该组件采用了组件与逻辑分离的设计思路,通过自定义 Hook 实现核心滚动逻辑,提高了代码的可复用性和灵活性。除了依赖 Vue3 和 Less 这种常规组件,可以开封即用。

2. 架构设计

组件采用了"关注点分离"的设计理念,将 UI 表现与业务逻辑分开:

AutoScrollList 组件
UI 表现层
useAutoScroll Hook
模板结构
样式定义
滚动状态管理
位置计算
时间控制
使用方

核心架构特点:

  1. 组件与逻辑分离:核心滚动逻辑被抽象到 useAutoScroll Hook 中
  2. 可组合性:Hook 可独立使用,也可以集成在组件中
  3. 插槽设计:通过 Vue 的插槽系统实现内容的高度自定义

实现逻辑与数据流

数据流转
AutoScrollList 组件
useAutoScroll Hook
接收参数
定义
定义
定义
生成
计算
设置
修改
清除
调用
调用
传递参数
获取
获取
获取
获取
获取
使用
使用
使用
暴露
暴露
触发
改变
更新
更新
用户数据
定时器
调用Hook
Props定义
displayItems
isSliding
getItemPosition
startScroll
stopScroll
模板渲染
方法暴露
状态管理
初始化配置
currentIndex
isSliding
timer
displayItems
计算属性
getItemPosition
位置计算
startScroll
控制方法
stopScroll
onMounted
生命周期
onBeforeUnmount

核心方法和状态详解

input
manages
computes
AutoScrollOptions
+Array items
+number itemHeight
+number? itemGap
+number visibleItems
+number? scrollInterval
+number? transitionDuration
+boolean? autoScroll
useAutoScrollReturn
+Ref displayItems
+Ref isSliding
+Ref currentIndex
+Function getItemPosition
+Function startScroll
+Function stopScroll
InternalState
+Ref<number> currentIndex
+Ref<boolean> isSliding
+Ref<number|null> timer
DisplayItem
+original item properties
+string key
+boolean preload

3. 核心实现逻辑

useAutoScroll Hook

import { ref, computed, onMounted, onBeforeUnmount } from 'vue';export interface AutoScrollOptions {items: any[];                   // 数据项数组itemHeight: number;             // 单项高度itemGap?: number;               // 项目间距visibleItems: number;           // 可见项目数scrollInterval?: number;        // 滚动间隔(毫秒)transitionDuration?: number;    // 过渡动画时长(毫秒)autoScroll?: boolean;           // 是否自动滚动
}export function useAutoScroll(options: AutoScrollOptions) {const {items,itemHeight,itemGap = 0,visibleItems,scrollInterval = 3000,transitionDuration = 500,autoScroll = true} = options;// 状态管理const currentIndex = ref(0);const isSliding = ref(false);const timer = ref<number | null>(null);// 计算属性const displayItems = computed(() => {const result = [];const totalItems = items.length;if (totalItems === 0) return [];// 当前显示的项目for (let i = 0; i < visibleItems + 1; i++) {const index = (currentIndex.value + i) % totalItems;result.push({...items[index],key: `${items[index].id}-${index}-${i}`, // 确保key的唯一性preload: i === visibleItems // 标记预加载项});}return result;});// 计算位置const getItemPosition = (index: number) => {return index * (itemHeight + itemGap);};// 控制方法const startScroll = () => {if (timer.value || items.length <= visibleItems) return;timer.value = window.setInterval(() => {isSliding.value = true;setTimeout(() => {currentIndex.value = (currentIndex.value + 1) % items.length;isSliding.value = false;}, transitionDuration);}, scrollInterval);};const stopScroll = () => {if (timer.value) {clearInterval(timer.value);timer.value = null;}};// 生命周期钩子onMounted(() => {if (autoScroll && items.length > visibleItems) {startScroll();}});onBeforeUnmount(() => {stopScroll();});return {displayItems,isSliding,currentIndex,getItemPosition,startScroll,stopScroll};
}

滚动原理与动画流程

组件挂载 startScroll 定时器 状态变更 视图更新 调用开始滚动 设置定时器 设置isSliding为true 触发动画过渡 预加载项变为可见 延时后更新currentIndex 设置isSliding为false 更新显示项列表 预加载项准备下一轮 循环执行... 组件挂载 startScroll 定时器 状态变更 视图更新

组件实现

<template><div class="auto-scroll-list":style="{ height: `${containerHeight}px` }"><template v-if="displayItems.length > 0"><slotv-for="(item, index) in displayItems":key="item.key"name="item":item="item":position="getItemPosition(index)":is-sliding="isSliding":is-preload="item.preload"></slot></template><template v-else><slot name="empty"></slot></template></div>
</template><script setup lang="ts">
import { useAutoScroll } from './useAutoScroll';const props = defineProps({items: {type: Array,required: true},itemHeight: {type: Number,required: true},itemGap: {type: Number,default: 0},containerHeight: {type: Number,required: true},visibleItems: {type: Number,required: true},scrollInterval: {type: Number,default: 3000},transitionDuration: {type: Number,default: 500},autoScroll: {type: Boolean,default: true}
});const { displayItems, isSliding, getItemPosition,startScroll,stopScroll
} = useAutoScroll({items: props.items,itemHeight: props.itemHeight,itemGap: props.itemGap,visibleItems: props.visibleItems,scrollInterval: props.scrollInterval,transitionDuration: props.transitionDuration,autoScroll: props.autoScroll
});// 暴露方法
defineExpose({startScroll,stopScroll
});
</script><style lang="less" scoped>
.auto-scroll-list {position: relative;overflow: hidden;
}
</style>

4. 使用示例

以下是组件的三种典型使用场景:

基础用法

<auto-scroll-list:items="notificationItems":item-height="80":container-height="250":visible-items="3"
><template #item="{ item, position, isSliding, isPreload }"><divclass="notification-item":style="{ transform: `translateY(${position}px)` }":class="{ sliding: isSliding, preload: isPreload }"><div class="title">{{ item.title }}</div><div class="content">{{ item.content }}</div></div></template><template #empty><div class="empty-message">暂无通知</div></template>
</auto-scroll-list>

自定义样式的告警列表

<auto-scroll-list:items="alertItems":item-height="80":item-gap="10":container-height="250":visible-items="3":scroll-interval="5000"
><template #item="{ item, position, isSliding, isPreload }"><divclass="alert-item":class="{'high-priority': item.priority === 'high','medium-priority': item.priority === 'medium','low-priority': item.priority === 'low',sliding: isSliding,preload: isPreload}":style="{ transform: `translateY(${position}px)` }"><div class="alert-badge">{{ item.priority === 'high' ? '!' : '⚠' }}</div><div class="alert-content"><div class="alert-title">{{ item.title }}</div><div class="alert-message">{{ item.message }}</div></div></div></template>
</auto-scroll-list>

直接使用 Hook 自定义实现

<template><div class="custom-list" :style="{ height: `${containerHeight}px` }"><div v-for="(item, index) in displayItems" :key="item.key"class="task-item":style="{ transform: `translateY(${getItemPosition(index)}px)` }":class="{ sliding: isSliding, preload: item.preload }"><!-- 自定义内容 --></div></div>
</template><script setup>
import { useAutoScroll } from './useAutoScroll';// 自定义实现
const containerHeight = 250;
const { displayItems, getItemPosition, isSliding,startScroll,stopScroll
} = useAutoScroll({items: taskItems.value,itemHeight: 80,itemGap: 10,visibleItems: 3,autoScroll: true
});
</script>

用户交互过程

onMounted自动触发
用户调用stopScroll
用户调用startScroll
组件卸载时
初始状态
自动滚动
scrollInterval时间后
isSliding = true
transitionDuration时间后
currentIndex + 1
等待间隔
开始过渡
过渡中
更新索引
暂停滚动

5. 技术优劣分析

优势

  1. 关注点分离:将滚动逻辑与UI表现分离,提高代码可维护性
  2. 高度复用性:Hook 可独立使用,适用于不同场景
  3. 良好的扩展性:通过插槽系统支持高度自定义的内容
  4. 配置灵活:支持多种滚动参数配置,适应不同业务需求
  5. 无外部依赖:不依赖第三方库,减少项目体积

劣势

  1. 性能考虑:对于大量数据,需要考虑虚拟列表优化
  2. 动画限制:当前仅支持垂直方向滚动,水平滚动需额外开发
  3. 复杂场景适应性:对于需要拖拽或交互复杂的场景支持有限
  4. 不支持嵌套列表:当前设计不适合嵌套滚动列表的场景
  5. 浏览器兼容性:使用了现代CSS特性,可能需要额外的兼容处理

性能分析

性能影响因素
数据量
DOM操作
计算复杂度
动画效果
列表项超过100个时可能出现性能问题
使用absolute定位减少重排
O(n)复杂度,n为可见项+1
使用CSS transform提高动画性能

6. 可改进方向

当前版本
性能优化
滚动方向支持
交互增强
动画扩展
辅助功能
虚拟列表
懒加载
水平滚动
多方向滚动
拖拽支持
排序功能
多种过渡效果
自定义动画
键盘导航
Screen Reader优化

技术路线演进

timelinetitle AutoScrollList 组件演进路线section 当前版本1.0 : 基础垂直滚动功能Hook与组件分离设计插槽系统支持section 短期迭代1.1 : 水平滚动支持性能优化1.2 : 响应式增强多种动画效果section 中期规划2.0 : 虚拟列表实现多方向滚动拖拽排序支持section 长期目标3.0 : 完整无障碍支持高级自定义API更多交互模式
  1. 虚拟列表支持:对大数据量进行优化,只渲染可视区域的数据
  2. 水平滚动支持:扩展当前的垂直滚动逻辑,支持水平方向滚动
  3. 更多交互方式:添加拖拽、手势支持等交互方式
  4. 动画多样化:提供更多滚动动画效果选择
  5. 响应式支持增强:更好地适应不同设备和屏幕尺寸
  6. 无障碍支持:增加对屏幕阅读器的支持,提高可访问性

7. 总结

AutoScrollList 组件通过组件与逻辑分离的设计,实现了一个灵活、可复用的自动滚动列表解决方案。它的核心价值在于:

  1. 简化复杂逻辑:封装了滚动、位置计算、过渡动画等复杂逻辑
  2. 提高开发效率:通过简单配置即可实现自动滚动效果
  3. 保持灵活性:支持多种自定义方式,适应不同业务场景

以下是组件实现的关键技术点:

mindmaproot((AutoScrollList))Hook设计状态管理currentIndexisSlidingtimer生命周期集成自动启动/停止返回值设计按需使用滚动机制定时器控制缓动动画预加载机制组件设计插槽系统item插槽empty插槽Props设计必要参数可选配置样式实现绝对定位CSS变换过渡效果

虽然存在一些局限性,但对于通知、公告、提醒等信息轮播的场景,该组件提供了一个简洁而有效的解决方案。通过未来的迭代优化,可以进一步提升组件的适用范围和性能表现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/35920.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JUC大揭秘:从ConcurrentHashMap到线程池,玩转Java并发编程!

目录 JUC实现类 ConcurrentHashMap 回顾HashMap ConcurrentHashMap CopyOnWriteArrayList 回顾ArrayList CopyOnWriteArrayList: CopyOnWriteArraySet 辅助类 CountDownLatch 线程池 线程池 线程池优点 ThreadPoolExecutor 构造器各个参数含义&#xff1a; 线程…

【unity实战】用unity封装一个复杂全面且带不同射击模式的飞机大战射击系统

考虑到每个人基础可能不一样,且并不是所有人都有同时做2D、3D开发的需求,所以我把 【零基础入门unity游戏开发】 分为成了C#篇、unity通用篇、unity3D篇、unity2D篇。 【C#篇】:主要讲解C#的基础语法,包括变量、数据类型、运算符、流程控制、面向对象等,适合没有编程基础的…

【AWS入门】Amazon EC2简介

【AWS入门】Amazon EC2简介 A Brief Introduction to Amazon EC2 By JacksonML 1. 背景 众所周知&#xff0c;互联网时代的用户每天需要访问Web站点&#xff0c;以获取不同的信息和数据。而海量的Web站点&#xff0c;其内容均存放在服务器上&#xff0c;无论服务器有多远&am…

PyTorch系列教程:基于LSTM构建情感分析模型

情感分析是一种强大的自然语言处理&#xff08;NLP&#xff09;技术&#xff0c;用于确定文本背后的情绪基调。它常用于理解客户对产品或服务的意见和反馈。本文将介绍如何使用PyTorch和长短期记忆网络&#xff08;LSTMs&#xff09;创建一个情感分析管道&#xff0c;LSTMs在处…

Vue 渲染 LaTeX 公式 Markdown 库

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

如何在WordPress中添加下载链接?

在WordPress网站上添加文件下载链接&#xff0c;不仅能提升用户体验&#xff0c;还能增加网站的互动性和实用价值。不管是提供免费的电子书、软件&#xff0c;还是其他类型的文件&#xff0c;下载链接都可以让用户快速获取所需的资源&#xff0c;增强他们对网站的好感。 本文将…

C/C++ 内存管理

1.C/C内存分布 sizeof和strlen有什么区别&#xff1a; 本质区别 特性sizeofstrlen类型运算符&#xff08;编译时计算&#xff09;库函数&#xff08;运行时计算&#xff09;作用对象变量、数据类型、表达式仅限以 \0 结尾的字符串&#xff08;char* 或字符数组&#xff09;功…

【C语言】:学生管理系统(多文件版)

一、文件框架 二、Data data.txt 三、Inc 1. list.h 学生结构体 #ifndef __LIST_H__ #define __LIST_H__#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #include <time.h>#define MAX_LEN 20// 学生信息…

【Spring】第三弹:基于 XML 获取 Bean 对象

一、获取 Bean 对象 1.1 根据名称获取 Bean 对象 由于 id 属性指定了 bean 的唯一标识&#xff0c;所以根据 bean 标签的 id 属性可以精确获取到一个组件对象。 1.确保存在一个测试类&#xff1a; public class HelloWorld {public void sayHello(){System.out.println(&quo…

Easysearch 索引生命周期管理实战

如果你的使用场景是对时序型数据进行分析&#xff0c;可能你会更重视最新的数据&#xff0c;并且可能会定期对老旧的数据进行一些处理&#xff0c;比如减少副本数、forcemerge、 删除等。Easysearch 的索引生命周期管理功能&#xff0c;可以自动完成此类索引的管理任务。 创建…

ARMv8.x-M架构计算能力概览

1.ARMv8.xM架构提供了哪些计算能力&#xff1f; ARMv7-M时代&#xff0c;Cortex-M系列CPU以提供通用计算能力为主。ARMv8-M架构提供了更加多样的计算能力。 首先&#xff0c;提供Thumb2指令集提供整数通用计算能力。 其次&#xff0c;ARMv8.x-M架构手册明确列出了更多可选的CPU…

20. Excel 自动化:Excel 对象模型

一 Excel 对象模型是什么 Excel对象模型是Excel图形用户界面的层次结构表示&#xff0c;它允许开发者通过编程来操作Excel的各种组件&#xff0c;如工作簿、工作表、单元格等。 xlwings 是一个Python库&#xff0c;它允许Python脚本与Excel进行交互。与一些其他Python库&#x…

大模型GGUF和LLaMA的区别

GGUF&#xff08;Gigabyte-Graded Unified Format&#xff09;和LLaMA&#xff08;Large Language Model Meta AI&#xff09;是两个不同层面的概念&#xff0c;分别属于大模型技术栈中的不同环节。它们的核心区别在于定位和功能&#xff1a; 1. LLaMA&#xff08;Meta的大语言…

一周学会Flask3 Python Web开发-SQLAlchemy查询所有数据操作-班级模块

锋哥原创的Flask3 Python Web开发 Flask3视频教程&#xff1a; 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 我们来新建一个的蓝图模块-班级模块&#xff0c;后面可以和学生模块&#xff0c;实现一对多的数据库操作。 blueprint下新建g…

STM32学习【5】用按键控制LED亮灭(寄存器)以及对位运算的思考

目录 1. 看原理图2 使能GPIOAGPIOA时钟模块2.2 设置引脚GPIO输入2.3 读取引脚值 3. 关于寄存器操作的思考 写在前面 注意&#xff0c;这篇文章虽然说是用按键控制led亮灭&#xff0c;重点不在代码&#xff0c;而是关键核心的描述。 用寄存器的方式&#xff0c;通过key来控制led…

js,html,css,vuejs手搓级联单选

<!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>级联选择器</title><script src"h…

【Spring】第四弹:基于XML文件注入Bean对象

一、setter 注入Bean对象 1.创建Student对象 public class Student {private Integer id;private String name;private Integer age;private String sex;public Student() {}public Integer getId() {return id;}public void setId(Integer id) {this.id id;}public String …

DeepSeek私有化部署与安装浏览器插件内网穿透远程访问实战

文章目录 前言1. 本地部署OllamaDeepSeek2. Page Assist浏览器插件安装与配置3. 简单使用演示4. 远程调用大模型5. 安装内网穿透6. 配置固定公网地址 前言 最近&#xff0c;国产AI大模型Deepseek成了网红爆款&#xff0c;大家纷纷想体验它的魅力。但随着热度的攀升&#xff0c…

单目3d detection算法记录

1、centernet object as points 这篇文章的核心单目3d检测主要是利用中心点直接回归出3d模型的所有属性&#xff0c;head共享整个backbone&#xff0c;其中3d属性包括&#xff1a;2d目标中心点、2dw和h、2d offsets、3doffsets、3d dimmession、rot还有depth。 其中对应的dep…

MySQL程序

博主主页: 码农派大星. 数据结构专栏:Java数据结构 数据库专栏:数据库 JavaEE专栏:JavaEE 软件测试专栏:软件测试 关注博主带你了解更多知识 1. mysqld (MySQL服务器) mysqld也被称为MySQL服务器&#xff0c;是⼀个多线程程序&#xff0c;对数据⽬录进⾏访问管理(包含数据库…