大家好!先上图看看本次案例的整体效果。
实现思路:
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:;\" rel=\"external nofollow\" 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>
以上所述是小编给大家介绍的Vue.js实现大转盘抽奖总结及实现思路,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
© 版权声明
THE END
暂无评论内容