Vue3滚动轮播组件实现超标信息自动滚动

创建滚动轮播组件实现超标信息自动滚动

为了实现超出父容器高度时的自动轮播滚动效果,我们可以创建一个通用的滚动组件,通过插槽来包裹内容。

1. 组件代码如下

vue:/Users/dylan/Documents/GitHub/Supervision-of-cooking-fume/src/components/ScrollList.vue 复制代码
<template>
  <div 
    ref="container" 
    class="scroll-container" 
    :style="{ height: height }"
    @mouseenter="pauseScroll" 
    @mouseleave="resumeScroll"
  >
    <div 
      ref="wrapper"
      class="scroll-wrapper"
      :class="{ 'scrolling': isScrolling }"
      :style="{ animationDuration: `${duration}s`, animationPlayState: isPaused ? 'paused' : 'running' }"
    >
      <slot></slot>
      <!-- 当内容超出时,复制一份内容用于无缝滚动 -->
      <div v-if="needScroll" class="scroll-duplicate">
        <slot></slot>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick, watch } from 'vue';

const props = defineProps({
  // 容器高度
  height: {
    type: String,
    default: '100%'
  },
  // 滚动速度,单位秒
  duration: {
    type: Number,
    default: 20
  },
  // 是否自动开始滚动
  autoScroll: {
    type: Boolean,
    default: true
  },
  // 滚动延迟,单位毫秒
  delay: {
    type: Number,
    default: 500
  }
});

const container = ref(null);
const wrapper = ref(null);
const isScrolling = ref(false);
const isPaused = ref(!props.autoScroll);
const needScroll = ref(false);

// 检查是否需要滚动
const checkNeedScroll = async () => {
  await nextTick();
  if (!container.value || !wrapper.value) return;
  
  const containerHeight = container.value.clientHeight;
  const contentHeight = wrapper.value.scrollHeight / (needScroll.value ? 2 : 1);
  
  needScroll.value = contentHeight > containerHeight;
  
  if (needScroll.value && props.autoScroll) {
    startScroll();
  } else {
    stopScroll();
  }
};

// 开始滚动
const startScroll = () => {
  isScrolling.value = true;
  isPaused.value = false;
};

// 停止滚动
const stopScroll = () => {
  isScrolling.value = false;
};

// 暂停滚动
const pauseScroll = () => {
  isPaused.value = true;
};

// 恢复滚动
const resumeScroll = () => {
  if (needScroll.value) {
    isPaused.value = false;
  }
};

// 监听内容变化
const observer = ref(null);

onMounted(() => {
  // 初始检查
  setTimeout(checkNeedScroll, props.delay);
  
  // 监听内容变化
  if (window.MutationObserver) {
    observer.value = new MutationObserver(checkNeedScroll);
    if (wrapper.value) {
      observer.value.observe(wrapper.value, {
        childList: true,
        subtree: true,
        characterData: true
      });
    }
  }
  
  // 监听窗口大小变化
  window.addEventListener('resize', checkNeedScroll);
});

onUnmounted(() => {
  if (observer.value) {
    observer.value.disconnect();
  }
  window.removeEventListener('resize', checkNeedScroll);
});

// 监听props变化
watch(() => props.autoScroll, (newVal) => {
  isPaused.value = !newVal;
});

// 暴露方法给父组件
defineExpose({
  checkNeedScroll,
  startScroll,
  stopScroll,
  pauseScroll,
  resumeScroll
});
</script>

<style scoped>
.scroll-container {
  overflow: hidden;
  position: relative;
  width: 100%;
}

.scroll-wrapper {
  position: relative;
  width: 100%;
}

.scrolling {
  animation: scrollAnimation linear infinite;
}

@keyframes scrollAnimation {
  0% {
    transform: translateY(0);
  }
  100% {
    transform: translateY(-50%);
  }
}

.scroll-duplicate {
  /* 确保复制的内容样式与原内容一致 */
}
</style>

2. 使用示例

vue:/Users/dylan/Documents/GitHub/Supervision-of-cooking-fume/src/views/IndexView.vue 复制代码
<script setup>
import { ref, onMounted, onUnmounted, inject } from "vue";
// 导入依赖...
import ScrollList from "@/components/ScrollList.vue"; // 导入滚动组件

// 其他代码...
</script>

<template>
    <div>
        <ScrollList
            class="flex-1 w-full hide-scrollbar"
            :duration="30"
          >
            <div
              v-for="(item, index) in 100"
              :key="index"
            >
              {{item}}
            </div>
          </ScrollList>
    </div>
</template>

组件功能说明

  1. 自动检测:组件会自动检测内容是否超出容器高度,只有超出时才会启动滚动

  2. 无缝滚动:通过复制一份内容实现无缝循环滚动效果

  3. 交互控制:鼠标悬停时暂停滚动,移出时恢复滚动

  4. 可配置性

    • height:设置容器高度
    • duration:控制滚动速度
    • autoScroll:是否自动开始滚动
    • delay:初始检测延迟时间
  5. 响应式

    • 监听内容变化自动更新滚动状态
    • 监听窗口大小变化重新计算是否需要滚动

这个组件设计为通用组件,可以在项目中的其他需要滚动展示的地方复用,提高代码的可维护性和一致性。

相关推荐
king王一帅2 小时前
Incremark Solid 版本上线:Vue/React/Svelte/Solid 四大框架,统一体验
前端·javascript·人工智能
智航GIS7 小时前
10.4 Selenium:Web 自动化测试框架
前端·python·selenium·测试工具
前端工作日常7 小时前
我学习到的A2UI概念
前端
徐同保7 小时前
为什么修改 .gitignore 后还能提交
前端
一只小bit7 小时前
Qt 常用控件详解:按钮类 / 显示类 / 输入类属性、信号与实战示例
前端·c++·qt·gui
Mr -老鬼8 小时前
前端静态路由与动态路由:全维度总结与实践指南
前端
颜酱8 小时前
前端必备动态规划的10道经典题目
前端·后端·算法
wen__xvn8 小时前
代码随想录算法训练营DAY10第五章 栈与队列part01
java·前端·算法
大怪v9 小时前
前端佬们!!AI大势已来,未来的上限取决你的独特气质!恭请批阅!!
前端·程序员·ai编程
Mr -老鬼10 小时前
功能需求对前后端技术选型的横向建议
开发语言·前端·后端·前端框架