大家好!先上图看看本次案例的整体效果。
实现思路:
- 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 },