【Vue.js实战案例】- Vue.js实现大转盘抽奖总结
程序员文章站
2022-03-25 21:41:33
大家好!先上图看看本次案例的整体效果。 实现思路: 实现步骤如下: store: 以上就是大转盘抽奖核心步骤的整体思路,欢迎讨论。 Vue.js实战之游戏抽奖系列全集 ↓↓↓↓↓↓↓↓↓↓↓ 【Vue.js实战案例】- Vue.js实现老虎-机抽奖总结 【Vue.js实战案例】- Vue.js实现九 ......
大家好!先上图看看本次案例的整体效果。
实现思路:
- vue component实现大转盘组件,可以嵌套到任意要使用的页面。
- css3 transform控制大转盘抽奖过程的动画效果。
- 抽奖组件内使用钩子函数watch监听抽奖结果的返回情况播放大转盘动画并给用户弹出中奖提示。
- 中奖结果弹窗,为抽奖组件服务。
实现步骤如下:
- 构建api奖品配置信息和抽奖接口,vuex全局存放奖品配置和中奖结果数据信息。
api:export default { getprizelist () { let prizelist = [ { id: 1, name: '小米8', img: 'https://i1.mifile.cn/f/i/g/2015/cn-index/m8-140.png' }, { id: 2, name: '小米电视', img: 'https://i1.mifile.cn/f/i/g/2015/tv4a-43qc.png' }, { id: 3, name: '小米平衡车', img: 'https://i1.mifile.cn/f/i/g/2015/cn-index/scooter-140!140x140.jpg' }, { id: 4, name: '小米耳机', img: 'https://c1.mifile.cn/f/i/g/2015/video/pinpai140!140x140.jpg' } ] return prizelist }, lottery () { return { id: 4, name: '小米耳机', img: 'https://c1.mifile.cn/f/i/g/2015/video/pinpai140!140x140.jpg' } } }
store:
import lotteryapi from '../../api/lottery.api.js' const state = { prizelist: [], lotteryresult: {} } const getters = { prizelist: state => state.prizelist, lotteryresult: state => state.lotteryresult } const mutations = { setprizelist (state, { prizelist }) { state.prizelist = prizelist }, setlotteryresult (state, { lotteryresult }) { state.lotteryresult = lotteryresult } } const actions = { getprizelist ({ commit }) { let result = lotteryapi.getprizelist() commit('setprizelist', { prizelist: result }) }, lottery ({ commit }) { let result = lotteryapi.lottery() commit('setlotteryresult', { lotteryresult: result }) } } export default { state, getters, mutations, actions, namespaced: true }
- 编写抽奖组件,为保证通用性,组件只负责播放抽奖结果。接收两个数据和一个方法,如下:
数据一:预置的奖品列表数据(轮播奖品需要)
数据二:抽奖结果,播放抽奖动画和弹出中奖结果需要
方法:抽奖动作,返回的抽奖结果数据即为数据二,响应式传递给组件
大概代码思路如下(仅供参考,不可运行)<template> <section> <div class="lucky-item"> <img src="//www.cnblogs.com/images/cnblogs_com/codeon/878827/o_backimage.jpg" alt> <div class="lucky-box"> <img src="//www.cnblogs.com/images/cnblogs_com/codeon/878827/o_circle.jpg" alt> <ul id="wheel" class="wheel-list" :style="wheelstyle" :class="transition"> <li v-for="(prize,index) in slotprizes" :style="{transform: 'rotate('+index*45+'deg)'}" v-bind:key="index"> <div class="fan-item" style="transform: rotate(15deg) skewy(45deg);"></div> <div class="lucky-prize"> <h3>{{prize.name}}</h3> </div> </li> </ul> <div class="wheel-btn" @click="$emit('lottery')"> <a> <img src="//images.cnblogs.com/cnblogs_com/codeon/878827/o_go.jpg" alt> </a> </div> </div> <prize-pop :prize="lotteryresult" v-if="showprize" @closelotterypop="showprize=false" /> </div> </section> </template> <script> import prizepop from './common/prize-pop.vue' export default { name: 'bigturntable', data () { return { isstart: false, showprize: false, wheelstyle: { 'transform': 'rotate(0deg)' }, transition: 'transitionclear', playturns: 5 // 默认先旋转5圈 } }, components: { prizepop }, props: { prizes: { type: array, required: false }, lotteryresult: { type: object, default: () => { } } }, computed: { slotprizes () { var self = this console.log(self.prizes) let prizelist = [] prizelist.push({ ...self.prizes[0], slotindex: 1 }) prizelist.push({ name: '谢谢参与', slotindex: 2 }) prizelist.push({ ...self.prizes[1], slotindex: 3 }) prizelist.push({ name: '谢谢参与', slotindex: 4 }) prizelist.push({ ...self.prizes[2], slotindex: 5 }) prizelist.push({ name: '谢谢参与', slotindex: 6 }) prizelist.push({ ...self.prizes[3], slotindex: 7 }) prizelist.push({ name: '谢谢参与', slotindex: 8 }) console.log(prizelist) return prizelist } }, methods: { /** * 执行抽奖动画 */ playwheel (index) { }, /** * 获取中奖结果所在奖品列表中的索引,以确定抽奖动画最终落在哪个奖品 */ getprizeindex (prizeid) { } }, watch: { /** * 监听抽奖结果,一旦有中奖信息就开始执行抽奖动画 */ lotteryresult (newval, oldval) { var self = this if (newval.id && newval.id > 0) { let index = self.getprizeindex(newval.id) self.playwheel(index) } } } } </script>
- 弹出中奖结果组件,依附于抽奖组件,在上一步的执行抽奖结果动画结束后执行。
<template> <div class="subject-pop" style="z-index: 10;" v-if="prize.id>0"> <div class="subject-pop-mask"></div> <div class="subject-pop-box"> <h3>恭喜您</h3> <p> <img :src="prize.img" alt> </p> <h4>获得 <span></span> <span>{{prize.name}}</span> </h4> <div class="subject-pop-footer"> <a href="javascript:;" class="november-btn1" @click="closelotteryemit">知道了</a> </div> </div> </div> </template> <script> export default { props: { prize: { type: object, default: () => { return { id: 0 } } } }, methods: { closelotteryemit () { this.$emit('closelotterypop') } } } </script>
- 抽奖组件运用在需要使用的页面中,此页面需要为抽奖组件提前准备好预置奖品列表和中奖结果信息,并提供好抽奖方法供子组件(抽奖组件)触发,触发完更改抽奖结果响应式传入到抽奖组件中。
<template> <section> <div style="width:100%;text-align:center;margin:2rem 0;">您有一次抽奖机会,祝君好运~~~</div> <bigturntable :prizes="prizelist" :lotteryresult="lotteryresult" @lottery="lottery" /> </section> </template> <script> import { mapgetters, mapactions } from 'vuex' import bigturntable from '@/components/bigturntable.vue' export default { name: 'bigturntablerun', created () { var self = this self.getprizelist() }, components: { bigturntable }, computed: { ...mapgetters({ prizelist: 'lottery/prizelist', lotteryresult: 'lottery/lotteryresult' }) }, methods: { ...mapactions({ getprizelist: 'lottery/getprizelist', lottery: 'lottery/lottery' }) } } </script>
以上就是大转盘抽奖核心步骤的整体思路,欢迎讨论。