更新记录
1.0.4(2024-07-29) 下载此版本
修复一些文案错误
1.0.3(2024-07-29) 下载此版本
修复说明文挡其中一些错误
1.0.2(2024-07-29) 下载此版本
增加抽奖禁用状态 增加UI配置,最小化实现自定义UI
查看更多平台兼容性
Vue2 | Vue3 |
---|---|
√ | √ |
App | 快应用 | 微信小程序 | 支付宝小程序 | 百度小程序 | 字节小程序 | QQ小程序 |
---|---|---|---|---|---|---|
HBuilderX 3.1.0 | × | √ | × | × | × | √ |
钉钉小程序 | 快手小程序 | 飞书小程序 | 京东小程序 |
---|---|---|---|
× | × | × | × |
H5-Safari | Android Browser | 微信浏览器(Android) | QQ浏览器(Android) | Chrome | IE | Edge | Firefox | PC-Safari |
---|---|---|---|---|---|---|---|---|
√ | √ | √ | √ | × | × | × | × | × |
hbxw-nine-square-grid-lottery组件
介绍
自定义宫格抽奖组件,支持完全自定义UI
组件提供默认九宫格UI,但考虑到形形色色的抽奖UI需求,抽奖UI支持完全自定义
考虑到网络请求需要一定的时间,所以组件留出了最小转圈数等待你设置抽奖奖品,在最小圈数的时候如果已经拿到抽奖奖品,会走最后一圈的奖品定位,如果没有拿到奖品则会继续走下去,直到转到最大圈数报抽奖失败。
使用示例
推荐先直接复制示例代码到工程中看效果了解下使用方法再投入项目使用。
<template>
<view class="container">
<text class="title">标准使用</text>
<hbxw-nine-square-grid-lottery
:list="list"
:luckPrice="luckPrice"
:luckyCount="luckyCount"
@luckEnd="luckEnd"
@luckStart="luckStartFn"
/>
<text class="title">自定义UI0</text>
<hbxw-nine-square-grid-lottery
:list="list0"
:isStart="startLuck"
:luckPrice="luckPrice0"
:luckyCount="luckyCount"
@luckEnd="luckEnd"
>
<template #default="{activePriceIndex}">
<view class="luck-container">
<view class="luck-item" v-for="(item, index) in list0" :key="item.id" :class="{active: index === activePriceIndex}">
<view class="luck-img-wrap">
<image class="luck-item-img" mode="widthFix" :src="item.img" :alt="item.name" />
</view>
<text class="luck-item-title">{{item.name}}</text>
</view>
<button @click="startLuckFn" :disabled="startLuck">点击抽奖,当前可抽奖次数{{luckyCount}}</button>
</view>
</template>
</hbxw-nine-square-grid-lottery>
<text class="title">自定义UI1</text>
<hbxw-nine-square-grid-lottery
:list="list"
:isStart="startLuck1"
:luckPrice="luckPrice1"
:luckyCount="luckyCount"
@luckEnd="luckEnd"
>
<template #default="{ prizeList, activeId }">
<view class="luck-container">
<template v-for="(item, index) in prizeList" :key="item.id">
<view class="tresure-chest" v-if="item.id === -1" @click="startLuckFn1">
<view class="tresure-chest-con">
<text class="tresure-chest-title">{{item.name}}</text>
<text class="tresure-chest-content">剩余次数: {{luckyCount}}</text>
</view>
</view>
<view v-else class="luck-item" :class="{active: item.id === activeId}">
<view class="luck-img-wrap">
<image class="luck-item-img" mode="widthFix" :src="item.img" :alt="item.name" />
</view>
<text class="luck-item-title">{{item.name}}</text>
</view>
</template>
</view>
</template>
</hbxw-nine-square-grid-lottery>
</view>
</template>
<script>
export default {
data() {
return {
list: [
{
img: 'https://placehold.jp/999999/ffffff/300x500.png?text=奖品图1',
name: '我是长奖品测一测省略1',
priceId: 1,
id: 1
}, {
img: 'https://placehold.jp/999999/ffffff/300x300.png?text=奖品图2',
name: '奖品2',
priceId: 2,
id: 2
}, {
img: 'https://placehold.jp/999999/ffffff/300x300.png?text=奖品图3',
name: '奖品3',
priceId: 3,
id: 3
}, {
img: 'https://placehold.jp/999999/ffffff/300x300.png?text=奖品图4',
name: '奖品4',
priceId: 4,
id: 4
}, {
img: 'https://placehold.jp/999999/ffffff/300x300.png?text=奖品图5',
name: '奖品5',
priceId: 5,
id: 5
}, {
img: 'https://placehold.jp/999999/ffffff/300x300.png?text=奖品图6',
name: '奖品6',
priceId: 6,
id: 6
}, {
img: 'https://placehold.jp/999999/ffffff/300x300.png?text=奖品图7',
name: '奖品7',
priceId: 7,
id: 7
}, {
img: 'https://placehold.jp/999999/ffffff/300x300.png?text=奖品图8',
name: '奖品8',
priceId: 8,
id: 8
}
],
list0: [
{
img: 'https://placehold.jp/999999/ffffff/300x500.png?text=奖品图1',
name: '我是长奖品测一测省略1',
priceId: 1,
id: 1
}, {
img: 'https://placehold.jp/999999/ffffff/300x300.png?text=奖品图2',
name: '奖品2',
priceId: 2,
id: 2
}, {
img: 'https://placehold.jp/999999/ffffff/300x300.png?text=奖品图3',
name: '奖品3',
priceId: 3,
id: 3
}, {
img: 'https://placehold.jp/999999/ffffff/300x300.png?text=奖品图4',
name: '奖品4',
priceId: 4,
id: 4
}, {
img: 'https://placehold.jp/999999/ffffff/300x300.png?text=奖品图5',
name: '奖品5',
priceId: 5,
id: 5
}, {
img: 'https://placehold.jp/999999/ffffff/300x300.png?text=奖品图6',
name: '奖品6',
priceId: 6,
id: 6
}, {
img: 'https://placehold.jp/999999/ffffff/300x300.png?text=奖品图7',
name: '奖品7',
priceId: 7,
id: 7
}, {
img: 'https://placehold.jp/999999/ffffff/300x300.png?text=奖品图8',
name: '奖品8',
priceId: 8,
id: 8
}, {
img: 'https://placehold.jp/999999/ffffff/300x300.png?text=奖品图9',
name: '奖品9',
priceId: 9,
id: 9
}
],
luckyCount: 3,
startLuck: false,
luckPrice: null,
luckPrice0: null,
startLuck1: false,
luckPrice1: null
}
},
methods: {
luckStartFn() {
console.log('---- luckStartFn ----:抽奖开始');
setTimeout(() => {
this.luckPrice = this.list[3];
}, 1000)
},
startLuckFn() {
this.startLuck = true;
setTimeout(() => {
this.luckPrice0 = this.list[4];
})
},
startLuckFn1() {
this.startLuck1 = true;
setTimeout(() => {
this.luckPrice1 = this.list[4];
})
},
luckEnd(e) {
console.log('---- luckend ----:', e);
// 表示抽奖成功了
if (e.status === 'ok') {
this.luckyCount -= 1;
}
if (e.result) {
uni.showToast({
icon: 'none',
title: `当前中奖奖品:${e.result.name}`
})
} else {
if (e.luckyCount <= 0) {
uni.showToast({
icon: 'none',
title: '暂无抽奖次数'
})
}
}
// 抽完奖要置位,以用于下次触发抽奖
setTimeout(() => {
this.startLuck = false;
this.startLuck1 = false;
e.reset && e.reset();
}, 1000);
}
}
}
</script>
<style lang="scss" scoped>
.container{
overflow: hidden;
min-height: 100vh;
background-color: green;
}
.title{
font-size: 32rpx;
margin: 20rpx 10rpx;
color: white;
}
// 自定义样式
.luck-container{
display: flex;
flex-direction: row;
justify-content: space-between;
flex-wrap: wrap;
padding: 20rpx;
}
.luck-item {
width: 226rpx;
height: 226rpx;
flex: none;
padding: 10rpx 15rpx;
margin-bottom: 10rpx;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
background-color: #F6F8FA;
border-radius: 20rpx;
border: 2px solid transparent;
&.active{
background-color: #D3E9FF;
border: 2px solid #2964E6;
}
.luck-item-title{
width: 100%;
text-align: center;
font-size: 24rpx;
line-height: 36rpx;
overflow: hidden;
flex: none;
text-overflow: ellipsis;
white-space: nowrap;
color: #A08866;
}
.luck-img-wrap{
width: 100%;
display: flex;
align-items: center;
justify-content: center;
flex: 1;
overflow: hidden;
}
.luck-item-img{
width: 100%;
}
}
.tresure-chest {
width: 226rpx;
height: 226rpx;
border-radius: 20rpx;
overflow: hidden;
cursor: pointer;
position: relative;
background-color: #2964E6;
background-image: linear-gradient(-61deg, #2964E6, #4C93FF);
.tresure-chest-con{
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
z-index: 2;
font-size: 45rpx;
font-weight: bold;
color: #fff;
}
.tresure-chest-content{
font-size: 30rpx;
color: #FFFFFF;
}
.tresure-chest-title{
font-size: 42rpx;
font-weight: bold;
margin-bottom: 20rpx;
color: #FFFFFF;
}
}
</style>
API
Props
属性名 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
list | Array | null | 是 | 当前要抽奖数据 |
speed | Number | 100 | 否 | 切换一格的时间间隔 |
speedLast | Number | 300 | 否 | 最后一圈切换一格的时间间隔,一般会speed的慢,制作紧张感 |
circleMin | Number | 2 | 否 | 至少转多少圈,到了这个圈数后面的每一圈都会检查是否设置了中奖奖品数据 |
circleMax | Number | 5 | 否 | 最多转多少圈,转到这个圈数如果发现还没有检查到中奖奖品数据,即判定为抽奖失败 |
isStart | Boolean | false | 否 | 用于自定义UI的情触发抽奖转盘,如果用默认UI,该参数不需要用 |
luckPrice | Object | null | 是 | 当前中奖数据 |
luckyCount | Number | 0 | 是 | 当前可抽奖次数 |
btnText | String | 点击抽奖 | 否 | 当前抽奖按钮上文案 |
luckStyle | Object | 抽奖容器样式 | 否 | 抽奖容器样式,最小成本实现自定义UI |
itemStyle | Object | 抽奖项样式 | 否 | 抽奖项样式,最小成本实现自定义UI |
itemActiveStyle | Object | 抽奖项高亮样式 | 否 | 抽奖项高亮样式,最小成本实现自定义UI |
itemTextStyle | Object | 抽奖项文本样式 | 否 | 抽奖项文本样式,最小成本实现自定义UI |
itemTextActiveStyle | Object | 抽奖项文本亮亮样式 | 否 | 抽奖项文本亮亮样式,最小成本实现自定义UI |
btnStyle | Object | 抽奖按钮样式 | 否 | 抽奖按钮样式,最小成本实现自定义UI |
btnDisableStyle | Object | 抽奖按钮禁用样式 | 否 | 禁用状态下抽奖按钮样式,最小成本实现自定义UI |
btnTitleStyle | Object | 抽奖按钮主文本样式 | 否 | 抽奖按钮主文本样式,最小成本实现自定义UI |
btnDisableTitleStyle | Object | 抽奖禁用下按钮主文本样式 | 否 | 抽奖禁用下按钮主文本样式,最小成本实现自定义UI |
btnSubTitleStyle | Object | 抽奖按钮次主文本样式 | 否 | 抽奖按钮次主文本样式,最小成本实现自定义UI |
btnDisableSubTitleStyle | Object | 抽奖禁用下按钮次要文本样式 | 否 | 抽奖禁用下按钮次要文本样式,最小成本实现自定义UI |
isDisabled | Boolean | 抽奖禁用 | 否 | 禁用抽奖,主动设置为true或者当前抽奖次数为0都会进入抽奖禁用状态 |
Event
事件名 | 说明 | 返回值 |
---|---|---|
luckStart | 抽奖开始触发的事件,主要是给使用默认UI用的,用于外面触发抽奖接口获取抽奖奖品 | 无 |
luckEnd | 抽奖结束触发的事件 | 抽奖结果对象{ result: 抽奖结果, luckyCount: 当前抽奖余下的次数, status: 抽奖状态 ok成功/error失败, reset: 抽奖重置方法爆露,用于外面重置抽奖 } |
注:包体积显示994kb,是因为有二张示例图片,真正会打包到项目中的体积是只有10k左右