vue3+TS 手动实现表格滚动

第一步定义变量

// 定义滚动定时器

const scrollInterval = ref<number | null>(null)

// 定义是否悬浮

const isHovered = ref(false)

// 定义初始化定时器

const initTimer = ref<number | null>(null)

// 定义底部暂停定时器

const bottomPauseTimer = ref<number | null>(null)

// 定义是否滚动到底部

const isAtBottom = ref(false)

// 是否滚动中

const isScrolling = ref(false)

第二部再html部分撰写内容

html 复制代码
<div
      class="content-box"
      ref="contentBoxRef"
      @mouseenter="isHovered = true"
      @mouseleave="isHovered = false"
    >
      <div v-for="(item, index) in props.dataList" :key="index" class="content-item">
        <template v-for="(row, number) in props.headerList" :key="row.key">
          <div class="row-item" :style="getRowItemStyle(row)">
            <img v-if="!number" class="ranking-item" :src="getImg(index)" alt="排位" />
            <span class="ellipsis-text">{{ item[row.key] }}</span>
          </div>
        </template>
      </div>
    </div>

第三步进行js代码部分撰写

javascript 复制代码
/**
   * @description: 启动自动滚动
   * @return {void}
   */
  const startAutoScroll = () => {
    if (scrollInterval.value || isScrolling.value) return

    // 初始延迟5秒
    isScrolling.value = false
    initTimer.value = window.setTimeout(() => {
      isScrolling.value = true
      doScroll()
    }, 3000)
  }

  /**
   * @description: 执行滚动
   * @return {void}
   */
  const doScroll = () => {
    if (scrollInterval.value) return

    scrollInterval.value = window.setInterval(() => {
      if (!contentBoxRef.value || isHovered.value || !isScrolling.value) return

      const { scrollTop, scrollHeight, clientHeight } = contentBoxRef.value
      const canScroll = scrollHeight > clientHeight
      const reachedBottom = scrollTop + clientHeight >= scrollHeight - 1

      if (canScroll) {
        if (reachedBottom && !isAtBottom.value) {
          // 到达底部,暂停5秒
          isAtBottom.value = true
          isScrolling.value = false
          if (scrollInterval.value) clearInterval(scrollInterval.value)
          scrollInterval.value = null

          bottomPauseTimer.value = window.setTimeout(() => {
            // 暂停结束后回到顶部
            contentBoxRef.value!.scrollTop = 0
            isAtBottom.value = false
            isScrolling.value = false
            startAutoScroll() // 重新开始滚动
          }, 3000)
        } else if (!reachedBottom) {
          // 正常滚动
          contentBoxRef.value.scrollBy({
            top: 1,
            behavior: 'smooth',
          })
        }
      }
    }, 50) as unknown as number
  }

  /**
   * @description: 停止所有滚动和定时器
   * @return {void}
   */
  const stopAllScroll = () => {
    if (initTimer.value) {
      clearTimeout(initTimer.value)
      initTimer.value = null
    }
    if (bottomPauseTimer.value) {
      clearTimeout(bottomPauseTimer.value)
      bottomPauseTimer.value = null
    }
    if (scrollInterval.value) {
      clearInterval(scrollInterval.value)
      scrollInterval.value = null
    }
    isScrolling.value = false
    isAtBottom.value = false
  }


  // 调用接口之后删除
  onMounted(() => {
    // 启动自动滚动(会有初始5秒延迟)
    startAutoScroll()
  })

  onUnmounted(() => {
    // 组件卸载时清除所有定时器
    stopAllScroll()
  })
相关推荐
踩着两条虫5 分钟前
VTJ.PRO AI Agent 技术白皮书
前端·vue.js·低代码
子兮曰5 分钟前
解剖 Claude Code:从入口架构逆向工程看 AI 编程工具的信任边界设计
前端·后端·claude
先吃饱再说17 分钟前
层层传递太“痛”了:useContext 给 React 组件装了个“无线遥控器”
前端·react.js·前端框架
颜进强21 分钟前
前端看后端 15:什么是 DNS?
前端·后端·ai编程
文艺理科生25 分钟前
LangChain.js-v1-记忆管理最佳实践
前端·javascript·后端
子兮曰32 分钟前
Elysia vs Hono 完整性能对比:Bun 专属优化还是跨平台通用,2026 实测数据给出的答案
前端·后端·typescript
To_OC1 小时前
从一个颜色选择器说起:我终于整明白了 React+TS 里的 model 与 api 分层
前端·react.js·typescript
赵大仁1 小时前
浏览器端 RAG:Transformers.js + WebGPU 本地检索入门
前端·ai·react·webgpu·rag
zyplayer-doc1 小时前
同一份制度别复制到多个知识库:用zyplayer-doc引用文档解决重复维护
javascript·人工智能·智能手机·开源·ocr
木叶丸1 小时前
从 Loop 到 Graph:AI 智能体协作系统工程指南
前端·后端·架构