更新记录
1.0.0(2026-08-19) 下载此版本
首次提交,详情如下
平台兼容性
uni-app(3.8.2)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| × | √ | √ | - | √ | - | √ | - | - |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | - | - | - | - | - | - | - | - | - | - | - |
qihuis-marquee 跑马灯随机选择器
一款基于 uni-app 的横向轮播 + 抽奖选择组件。以当前选中项为中心,向左右各延伸展示,支持触摸滑动切换、抽奖式滚动选人、动态成员增删,适用于游戏房间、组队选人、随机点名等场景。
可访问下面二维码进入【多人模式】体验组件交互:

功能特点
- 环形循环轮播:首尾相连,滑动到末尾自动回到开头
- 居中放大突出:当前选中项放大 1.1 倍,视觉焦点明确
- 默认五头像同屏展示:中间 1 个 + 左右各 2 个,其余自动隐藏
- 自定义展示个数:设置showCount即可
- 触摸滑动切换:左右滑动即可查看并切换其他成员头像
- 抽奖滚动选择:支持随机抽取或指定结果,滚动时长可配置
- 动态成员追踪:成员列表增删时按 id 追踪选中项,不会错位
- 样式自由定制:本组件仅提供核心功能实现,默认样式较为基础,可参考下面示例代码自行设计。组件代码并不十分复杂,下载插件后稍加研读可自行扩展
快速使用
1. 示例代码
<template>
<view class="container">
<view class="user-list-card-wrapper">
<view class="card-header">
<view class="title-group">
<view class="main-title">参与者</view>
<view class="sub-title">{{ memberList.length }}人</view>
</view>
<view class="button-group">
<button class="btn" @click="stopAnimated">停止</button>
<button class="btn" @click="chooseItem">选择</button>
</view>
</view>
<!-- 玩家组件 -->
<qihuis-marquee ref="playersRef" height="250rpx" item-width="60px" :show-count="3" :item-list="memberList"
:choose-timeout="duration"></qihuis-marquee>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue';
import { onLoad,onUnload } from '@dcloudio/uni-app';
const playersRef = ref(null)
const memberList = ref([])
const duration = ref(3)
onLoad(()=>{
uni.$on("currentMarqueeIdChange",currentMarqueeIdChange)
setTimeout(()=>{
memberList.value = [
{id:1,name:"赵一",avatarUrl:"/static/logo.png"},
{id:2,name:"钱二",avatarUrl:"/static/logo.png"},
{id:3,name:"孙三",avatarUrl:"/static/logo.png"},
{id:4,name:"李四",avatarUrl:"/static/logo.png"},
{id:5,name:"周五",avatarUrl:"/static/logo.png"},
{id:6,name:"吴六",avatarUrl:"/static/logo.png"},
{id:7,name:"郑七",avatarUrl:"/static/logo.png"},
{id:8,name:"王八",avatarUrl:"/static/logo.png"}
]
},1000)
})
onUnload(()=>{
uni.$off("currentMarqueeIdChange",currentMarqueeIdChange)
})
function currentMarqueeIdChange(target){
console.log(target)
}
function stopAnimated(){
playersRef.value.stopAnimated()
}
function chooseItem(){
//指定用户id
// playersRef.value.chooseItem(3)
//完全随机选择
playersRef.value.chooseItem()
}
function clickUser(){
//和chooseItem的区别是,不会循环滚动,而是直接一步到位将目标用户居中展示
playersRef.value.clickItemById(7)
}
</script>
<style lang="scss" scoped>
.container{
padding: 30rpx;
min-height: 100vh;
background-color: skyblue;
.user-list-card-wrapper {
border-radius: 20rpx;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.2),
0 0 0 1px rgba(255, 255, 255, 0.05) inset;
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.1);
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx 30rpx 20rpx;
border-bottom: 1rpx solid rgba(255, 255, 255, 0.2);
.title-group {
display: flex;
align-items: center;
gap: 12rpx;
.main-title {
font-size: 32rpx;
font-weight: bold;
color: #FFFFFF;
text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.3);
}
.sub-title {
display: flex;
flex-direction: column;
justify-content: flex-end;
font-size: 26rpx;
color: rgba(255, 255, 255, 0.7);
}
}
.button-group {
display: flex;
justify-content: center;
align-items: center;
gap: 16rpx;
.btn {
padding: 8rpx 20rpx;
font-size: 24rpx;
border-radius: 8rpx;
background: linear-gradient(45deg, #8A6DE9, #667eea);
color: white;
border: none;
line-height: 1;
box-shadow: 0 4rpx 12rpx rgba(138, 109, 233, 0.3);
font-weight: 600;
&:active {
transform: scale(0.95);
opacity: 0.9;
}
}
}
}
}
}
</style>
属性说明(Props)
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
itemList |
Array | [] |
玩家列表,每项需包含 id、name、avatarUrl 三个字段 |
chooseTimeout |
Number | 3 |
抽奖滚动时长,单位:秒 |
height |
String | '250rpx' |
组件容器高度,支持任意合法 CSS 高度单位,如:px\rpx\vh\vw |
itemWidth |
String/Number | '250rpx' |
条目宽度,支持任意合法 CSS 高度单位,如:px\rpx\vh\vw,纯数字视为px |
showCount |
Number | null | 自定义展示元素个数,要求:>=1的奇数,比如:1、3、5、7、9。如果为偶数,会自动-1变成奇数 |
itemList 数据格式
[
{
id: 1, // 用户唯一标识,用于追踪选中项
name: "赵一", // 显示的用户名
avatarUrl: "/static/logo.png" // 头像图片路径
}
]
对外暴露方法
通过 ref 获取组件实例后调用:
chooseItem(id?)
开始抽奖式滚动选择。
| 参数 | 类型 | 说明 |
|---|---|---|
id |
Number / String | 可选。指定最终选中的用户 id;不传则完全随机 |
// 随机选择一名玩家
playersRef.value.chooseItem()
// 指定选择 id 为 3 的玩家
playersRef.value.chooseItem(3)
抽奖过程中再次调用会提示"请勿重复操作",不会重复触发。
clickItemById(id)
直接将指定成员头像居中展示,不经过滚动动画,一步到位。
| 参数 | 类型 | 说明 |
|---|---|---|
id |
Number / String | 必填。要居中展示的用户 id |
// 直接将 id=7 的玩家移到中间
playersRef.value.clickItemById(7)
与
chooseItem的区别:chooseItem会先循环滚动再定格,clickItemById直接切换。
stopAnimated()
立即停止当前正在进行的抽奖动画。
playersRef.value.stopAnimated()
事件说明
currentMarqueeIdChange
当前选中玩家发生变化时触发
触发时机:
| 场景 | 是否触发 |
|---|---|
| 点击某个头像 | 触发 |
调用 clickItemById |
触发 |
| 抽奖滚动过程中 | 不触发 |
| 抽奖结束定格时 | 触发一次 |
抽奖过程中不频繁触发事件,仅在最终定格时触发一次,避免业务逻辑被频繁打断。
平台兼容性
| 平台 | 兼容性 |
|---|---|
| H5 | 支持 |
| 微信小程序 | 支持 |
| App | 支持 |
| 其他小程序 | 理论支持,未逐一测试 |

收藏人数:
下载插件并导入HBuilderX
赞赏(0)
下载 5
赞赏 0
下载 12518243
赞赏 1943
赞赏
京公网安备:11010802035340号