可根据容器高度不断变化的竖向滚动组件


前言

之前有一个需求 当容器高度高度为640时 数据只有7条不满足滚动要求不滚动 当高度变为240时要求滚动 无缝滚动的容器的高度会变 当时使用 vue3-seamless-scroll 插件时 当高度变低时使用 vue3-seamless-scroll reset() 重置组件状态,如外层盒子大小改变时需调用该方法重置属性 不生效,于是自己搞一个


提示:以下是本篇文章正文内容,下面案例可供参考

1.创建 SeamlessScroll 文件

代码如下(示例):

<template>
  <div
    class="scroll-container"
    :style="{ height: `${props.height}px`, overflow: 'hidden' }"
    @mouseenter="pause"
    @mouseleave="resume"
  >
    <div ref="scrollContentRef" class="scroll-content" :style="scrollStyle">
      <slot></slot>
      <slot v-if="isOverflow"></slot>
      <!-- 仅在内容超出时重复 -->
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from "vue";

const props = defineProps({
  speed: {
    type: Number,
    default: 300, // 滚动速度(单位:像素/秒)
  },
  height: {
    type: Number,
    default: 300, // 默认高度
  },
});

const scrollContentRef = ref(null);
const isPaused = ref(false);

// 获取内容高度
const getContentHeight = () => {
  return scrollContentRef.value?.scrollHeight || 0;
};

// 判断内容是否超出容器高度
const isOverflow = computed(() => {
  const containerHeight = props.height;
  const contentHeight = getContentHeight();
  return contentHeight > containerHeight;
});

// 使用固定速度,不随数据量变化
const scrollDuration = computed(() => {
  // 真正保持固定的滚动速度:动画距离(实际为内容高度的50%) / 速度
  const contentHeight = getContentHeight();
  // 由于动画滚动了50%,而我们复制了内容,所以实际需要滚动的距离是内容高度
  return contentHeight / props.speed;
});

// 动态控制滚动样式
const scrollStyle = computed(() => {
  if (!isOverflow.value) return {}; // 不超出时不滚动
  return {
    animation: `scroll ${scrollDuration.value}s linear infinite`,
    animationPlayState: isPaused.value ? "paused" : "running",
  };
});

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

// 恢复滚动
const resume = () => {
  isPaused.value = false;
};
</script>

<style scoped>
.scroll-container {
  overflow: hidden;
}

.scroll-content {
  display: flex;
  flex-direction: column;
}
</style>

<style>
@keyframes scroll {
  0% {
    transform: translateY(0);
  }
  100% {
    transform: translateY(-50%);
  }
}
</style>

2.使用组件

代码如下(示例):

//根据一个状态 isShow 来判断高度的大小 填入 240 ,640 高度
<SeamlessScroll :speed="30" :height="isShow ? 240 : 640">
//需要滚动的结构 根据需求自行定义
	<div
	  v-for="(data, index) in List"
      :key="index"
	>
		***你的代码***
	</div>
</SeamlessScroll>

更多推荐