npm package: @hbis-uni/hbis-auto-scroll-list
Description: HBIS UNI auto scroll list component
Latest version: 1.0.1

# @hbis-uni/hbis-auto-scroll-list

一个丝滑顺畅的自动滚动列表组件，适用于中奖公示、公告列表等场景。

## 功能特性

- 丝滑顺畅的滚动效果，使用 requestAnimationFrame 实现
- 支持垂直和水平滚动方向
- 支持自定义滚动速度
- 支持鼠标悬停暂停
- 支持触摸和鼠标拖拽手动滚动
- 支持循环滚动
- 支持自定义列表项样式
- 提供丰富的API接口

## 安装

```bash
npm install @hbis-uni/hbis-auto-scroll-list
# 或
pnpm add @hbis-uni/hbis-auto-scroll-list
```

## 基础用法

```vue
<template>
  <hbis-auto-scroll-list :data="listData" />
</template>

<script setup>
import { ref } from 'vue';
import HbisAutoScrollList from '@hbis-uni/hbis-auto-scroll-list';

const listData = ref([
  '恭喜用户A中奖100元',
  '恭喜用户B中奖50元',
  '恭喜用户C中奖200元',
  '恭喜用户D中奖80元',
  '恭喜用户E中奖150元'
]);
</script>
```

## Props

| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|------|------|------|--------|--------|
| data | 列表数据 | Array | - | [] |
| speed | 滚动速度 | Number | - | 1 |
| direction | 滚动方向 | String | vertical / horizontal | vertical |
| pauseOnHover | 鼠标悬停是否暂停 | Boolean | - | true |
| itemHeight | 列表项高度（垂直滚动） | Number | - | 40 |
| itemWidth | 列表项宽度（水平滚动） | Number | - | 200 |
| containerHeight | 容器高度 | Number / String | - | 300 |
| containerWidth | 容器宽度 | Number / String | - | '100%' |
| loop | 是否循环滚动 | Boolean | - | true |
| customItemClass | 自定义列表项类名 | String | - | '' |
| itemStyle | 自定义列表项样式 | Object | - | {} |

## Events

| 事件名 | 说明 | 回调参数 |
|--------|------|----------|
| scroll | 滚动时触发 | 当前位置 |
| pause | 暂停时触发 | - |
| resume | 恢复时触发 | - |
| dragStart | 开始拖拽时触发 | - |
| dragEnd | 结束拖拽时触发 | - |

## Slots

| 插槽名 | 说明 | 参数 |
|--------|------|------|
| item | 自定义列表项 | item: 当前项数据, index: 索引 |

## Methods

| 方法名 | 说明 | 参数 |
|--------|------|------|
| pause | 暂停滚动 | - |
| resume | 恢复滚动 | - |
| scrollTo | 滚动到指定位置 | position: 位置值 |
| scrollToTop | 滚动到顶部 | - |
| scrollToBottom | 滚动到底部 | - |

## 高级用法

### 拖拽滚动

组件支持鼠标和触摸拖拽滚动，当用户开始拖拽时会自动暂停自动滚动，拖拽结束后恢复自动滚动。

```vue
<template>
  <hbis-auto-scroll-list 
    :data="listData"
    @drag-start="onDragStart"
    @drag-end="onDragEnd"
  />
</template>

<script setup>
import { ref } from 'vue';
import HbisAutoScrollList from '@hbis-uni/hbis-auto-scroll-list';

const listData = ref([
  '消息1',
  '消息2',
  '消息3'
]);

const onDragStart = () => {
  console.log('开始拖拽');
};

const onDragEnd = () => {
  console.log('结束拖拽');
};
</script>
```

### 自定义列表项样式

```vue
<template>
  <hbis-auto-scroll-list :data="listData" :item-style="{ background: '#f5f5f5', color: '#333' }">
    <template #item="{ item, index }">
      <div class="custom-item">
        <span class="index">{{ index + 1 }}.</span>
        <span class="content">{{ item }}</span>
        <span class="time">{{ item.time }}</span>
      </div>
    </template>
  </hbis-auto-scroll-list>
</template>

<script setup>
import { ref } from 'vue';
import HbisAutoScrollList from '@hbis-uni/hbis-auto-scroll-list';

const listData = ref([
  { content: '恭喜用户A中奖100元', time: '10:00' },
  { content: '恭喜用户B中奖50元', time: '10:05' },
  { content: '恭喜用户C中奖200元', time: '10:10' },
  { content: '恭喜用户D中奖80元', time: '10:15' },
  { content: '恭喜用户E中奖150元', time: '10:20' }
]);
</script>

<style scoped>
.custom-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 20px;
  background: linear-gradient(90deg, #f0f0f0, #ffffff);
  border-bottom: 1px solid #e0e0e0;
}

.index {
  color: #ff6b6b;
  font-weight: bold;
  margin-right: 10px;
}

.content {
  flex: 1;
  color: #333;
}

.time {
  color: #999;
  font-size: 12px;
}
</style>
```

### 水平滚动

```vue
<template>
  <hbis-auto-scroll-list 
    :data="listData" 
    direction="horizontal"
    :item-width="300"
    :container-height="100"
  />
</template>
```

### 控制滚动

```vue
<template>
  <div>
    <hbis-auto-scroll-list 
      ref="scrollListRef"
      :data="listData"
      @pause="onPause"
      @resume="onResume"
    />
    <div class="controls">
      <button @click="pause">暂停</button>
      <button @click="resume">继续</button>
      <button @click="scrollToTop">回到顶部</button>
      <button @click="scrollToBottom">滚动到底部</button>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import HbisAutoScrollList from '@hbis-uni/hbis-auto-scroll-list';

const scrollListRef = ref(null);
const listData = ref([
  '恭喜用户A中奖100元',
  '恭喜用户B中奖50元',
  '恭喜用户C中奖200元',
  '恭喜用户D中奖80元',
  '恭喜用户E中奖150元'
]);

const pause = () => {
  scrollListRef.value?.pause();
};

const resume = () => {
  scrollListRef.value?.resume();
};

const scrollToTop = () => {
  scrollListRef.value?.scrollToTop();
};

const scrollToBottom = () => {
  scrollListRef.value?.scrollToBottom();
};

const onPause = () => {
  console.log('滚动已暂停');
};

const onResume = () => {
  console.log('滚动已恢复');
};
</script>
```

### 中奖公示示例

```vue
<template>
  <div class="lottery-announcement">
    <div class="title">🎉 中奖公示 🎉</div>
    <hbis-auto-scroll-list 
      :data="winners" 
      :speed="0.8"
      :item-height="50"
      :container-height="400"
    >
      <template #item="{ item, index }">
        <div class="winner-item">
          <div class="rank">{{ getRankIcon(index) }}</div>
          <div class="user-info">
            <div class="username">{{ item.username }}</div>
            <div class="prize">获得 {{ item.prize }}</div>
          </div>
          <div class="time">{{ item.time }}</div>
        </div>
      </template>
    </hbis-auto-scroll-list>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import HbisAutoScrollList from '@hbis-uni/hbis-auto-scroll-list';

const winners = ref([
  { username: '用户***123', prize: 'iPhone 15 Pro', time: '2024-01-20 10:30' },
  { username: '用户***456', prize: 'iPad Air', time: '2024-01-20 10:25' },
  { username: '用户***789', prize: 'AirPods Pro', time: '2024-01-20 10:20' },
  { username: '用户***012', prize: 'Apple Watch', time: '2024-01-20 10:15' },
  { username: '用户***345', prize: '100元话费', time: '2024-01-20 10:10' },
  { username: '用户***678', prize: '50元红包', time: '2024-01-20 10:05' },
  { username: '用户***901', prize: '30元优惠券', time: '2024-01-20 10:00' },
  { username: '用户***234', prize: '20元红包', time: '2024-01-20 09:55' }
]);

const getRankIcon = (index) => {
  const icons = ['🥇', '🥈', '🥉'];
  return icons[index] || `${index + 1}`;
};
</script>

<style scoped>
.lottery-announcement {
  max-width: 600px;
  margin: 20px auto;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.title {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  text-align: center;
  padding: 20px;
  font-size: 24px;
  font-weight: bold;
}

.winner-item {
  display: flex;
  align-items: center;
  padding: 12px 20px;
  background: linear-gradient(90deg, #fafafa, #ffffff);
  border-bottom: 1px solid #f0f0f0;
  transition: all 0.3s ease;
}

.winner-item:hover {
  background: linear-gradient(90deg, #f0f0f0, #fafafa);
}

.rank {
  font-size: 24px;
  margin-right: 15px;
  min-width: 30px;
  text-align: center;
}

.user-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.username {
  font-weight: 500;
  color: #333;
}

.prize {
  font-size: 14px;
  color: #ff6b6b;
}

.time {
  font-size: 12px;
  color: #999;
  white-space: nowrap;
}
</style>
```

## 注意事项

1. 确保传入的 data 数组不为空
2. 自定义 itemHeight 或 itemWidth 时，请确保与实际样式一致
3. 使用 loop 模式时，列表数据会自动复制一份以实现无缝滚动
4. 滚动速度建议设置为 0.5-2 之间，过大可能导致滚动过快
5. 在组件销毁时会自动停止滚动，无需手动清理
6. 拖拽功能支持鼠标和触摸事件，拖拽时会自动暂停自动滚动
7. 拖拽结束后，如果之前不是暂停状态，会自动恢复滚动
8. 拖拽范围受容器大小限制，超出边界会自动停止

## License

MIT