需求:左边表格配置数据,右边渲染
后端返回数据:
//选项中的其中之一
{
"id": 7,
"name": "充电卡3.0",//奖品名称
"image":xxx,//奖品图片url地址
"content": "这是三张充电卡",//奖品描述
...
},
实现方法: Vue3生命周期+组件通信
(绘制转盘的方法在:vue3+ts 实现转盘抽奖 组件_喝可乐的大喵的博客-CSDN博客)
响应式组件:Spinner.vue
<template>
<LuckyWheel ref="myLucky" width="300px" height="300px" :prizes="prizes" :blocks="blocks" :buttons="buttons"
:defaultConfig="defaultConfig" @start="startCallback" @end="endCallback" />
</template>
<script lang="ts" setup>
import { LuckyDrawTableDataParams } from '@/types/activity';
import { ref, onUpdated, onMounted, onBeforeUpdate } from 'vue';
const props = defineProps<{
previewArr: LuckyDrawTableDataParams[]
}>()
//赋值
const applySpinner = () => {
props.previewArr.forEach((item) => {
prizes.push(
{
fonts: [{ text: item.number + item.activity_prize_name, top: '10%', fontSize: '14px', fontColor: '#e74b44' }],
background: '#ffeaa7',
imgs: [{
src: item.image as string,
width: '30%',
top: '40%',
left: '-2%'
}]
},
)
})
return prizes
}
//------生命周期
onMounted(() => {
if (props.previewArr) {
applySpinner()
}
})
onBeforeUpdate(() => {
prizes = []
})
onUpdated(() => {
if (props.previewArr) {
applySpinner()
}
})
//-----------------轮盘配置项
const blocks = [{
padding: '30px',
//边框图片
imgs: [{
src: 'xxx',
width: '110%',
height: '100%',
rotate: true
}]
},
]
//奖品数组
let prizes: any[] = []
//中心按钮
const buttons = [{
radius: '25%',
imgs: [{
src: 'xxx',
width: '100%',
top: '-130%'
}],
// background: '#fb8c76',
pointer: true,
fonts: [{ text: '点击\n抽奖', top: '-15px', left: '3px', fontSize: '16px', fontColor: '#fff' }]
}]
//设置间距
const defaultConfig = {
gutter: '5px'
}
// 点击抽奖按钮会触发star回调.
const myLucky = ref()
const startCallback = () => {
// 调用抽奖组件的play方法开始游戏
myLucky.value.play()
// 模拟调用接口异步抽奖
setTimeout(() => {
// 假设后端返回的中奖索引是0,此处设置随机数
const index = parseInt(Math.random() * prizes.length + '')
console.log(index)
// 调用stop停止旋转并传递中奖索引
myLucky.value.stop(index)
}, 3000)
}
// 抽奖结束会触发end回调
const endCallback = (prize: any) => {
console.log(prize)
}
</script>
父组件:
//表格数据
<el-table :data="drawData" max-height="500" style="width: 100%">
//预览按钮
<div class="bottom">
<el-button type="primary" color="#c3292a" @click="previewSpinner">预览</el-button>
</div>
<!-- 转盘 -->
<div class="preview">
<Spinner v-if="previewArr.length" :previewArr="previewArr"></Spinner>
</div>
<script setup lang="ts">
//点击预览
const previewArr = ref<LuckyDrawTableDataParams[]>([])
const previewSpinner = () => {
if (drawData.value.length > 8 || drawData.value.length < 4) return ElMessage.error('请设置4-8条奖品')
previewArr.value = drawData.value.map((item) => {
return {
activity_prize_id: item.activity_prize.activity_prize_id,
activity_prize_name: item.activity_prize.activity_prize_name,
prize_chance: item.prize_chance,
number: item.number,
image: item.activity_prize.image
}
})
}
</script>