Vue3는 Jiugongge 복권의 효과를 실현합니다.

머리말

오랜만에 글을 쓰네요 마지막으로 글을 올렸던게 연말정산이네요 눈깜짝할 사이에 또 ​​1년이네요 더 요약하고 싶을때마다 참을수가 없네요 어렵다. 이번에는 구공개 복권의 소소한 게임을 공유하겠습니다.원인은 회사가 최근에 포인트 복권을 할 필요가 있다는 것입니다.복권의 동적 효과를 요약하여 복권의 과정과 주의점을 실현하겠습니다. 처음부터 기능. 데모 기능 코드는 결합된 API를 주로 사용하는 vue3를 사용하여 구현되었으며 단순 데모이므로 스캐폴딩 및 패키징 도구를 사용하지 않습니다.

수요와 효과

요구 사항: 1. 배경 구성에 따라 선물이 생성됩니다. 2. 마키 회전 효과 3. 결과는 배경에서 생성되며 각 선물의 확률이 다릅니다(확률은 여기서 논의하지 않음).

주의사항: 1. 레이아웃 정렬 방법, 런닝에 따라 정렬하는지 위에서 아래로 왼쪽에서 오른쪽으로 2. 클릭 버튼 삽입 방법, DOM 구조 생성 방법 3. 레이아웃 구현 방법 경마의 효과 및 속도 제어 방법 4. 인터페이스 처리 방법 인터페이스 오류 보고, 요청 시 특수 효과 5 Pending, 경마 후 선택한 결과와 일치하는 배경 반환 결과 등

최종 렌더링:

참고: 사진은 모두 Baidu 사진에서 찾을 수 있습니다.

기능 구현

1단계: 레이아웃 구현

아이디어: 백그라운드에서 구성된 선물 목록 요청 일반적으로 참여 감사를 포함하여 8개의 선물이 구성됩니다. 배치. 두 번째는 순회할 수 있습니다. 여기서는 순회 방법을 사용하지만 버튼은 선물 목록 배열에 삽입해야 합니다. css 코드는 플렉스 레이아웃을 사용할 수 있으며 세 개의 행과 세 개의 열이 적합하며 필요한 스타일을 추가합니다. js 부분은 주로 splice() 메서드를 사용하여 <시작 버튼>을 삽입합니다.

코드의 일부:

<body><div id="app" v-cloak><div class="container"><div :class="['item', {'active': currentIndex === index}]"v-for="(item, index) in prizeList"@click="start(index)"><img :src="item.pic" alt=""><p v-if="index !== 4">{
   
   { item.name }}</p></div></div></div>
</body> 
const state = reactive({prizeList: [{ name: '手机', pic: 'https://bkimg.cdn.bcebos.com/pic/3801213fb80e7bec54e7d237ad7eae389b504ec23d9e' },{ name: '手表', pic: 'https://img1.baidu.com/it/u=2631716577,1296460670&fm=253&fmt=auto&app=120&f=JPEG' },{ name: '苹果', pic: 'https://img2.baidu.com/it/u=2611478896,137965957&fm=253&fmt=auto&app=138&f=JPEG' },{ name: '棒棒糖', pic: 'https://img2.baidu.com/it/u=576980037,1655121105&fm=253&fmt=auto&app=138&f=PNG' },{ name: '娃娃', pic: 'https://img2.baidu.com/it/u=4075390137,3967712457&fm=253&fmt=auto&app=138&f=PNG' },{ name: '木马', pic: 'https://img1.baidu.com/it/u=2434318933,2727681086&fm=253&fmt=auto&app=120&f=JPEG' },{ name: '德芙', pic: 'https://img0.baidu.com/it/u=1378564582,2397555841&fm=253&fmt=auto&app=120&f=JPEG' },{ name: '玫瑰', pic: 'https://img1.baidu.com/it/u=1125656938,422247900&fm=253&fmt=auto&app=120&f=JPEG' }], // 后台配置的奖品数据
})
const startBtn = { name: '开始按钮', pic: 'https://img2.baidu.com/it/u=1497996119,382735686&fm=253' }

onMounted(() => {// state.prizeList.forEach((item, index) => {//item.id = index// })state.prizeList.splice(4, 0, startBtn)console.log(state.prizeList)
}) 
두 번째 단계: 동적 효과 실현

아이디어 마키 효과의 구현은 주로 원 안에 강조 표시하는 것으로 여기서 현재 선물 좌표와 경마가 수행한 걸음 수를 8로 나눈 나머지가 같다고 생각할 수 있습니다. 는 선물 목록과 다르기 때문에 경마에 의해 실행되는 선물 좌표의 시퀀스 배열을 정의할 수 prizeSort = [0, 1, 2, 5, 8, 7, 6, 3]있으므로 원형으로 실행됩니다. 그런 다음 애니메이션이 단계별로 실행되면 타이머를 사용하고 현재 강조 표시된 첨자 인덱스 currentIndex가 간격으로 회전 수를 변경하도록 할 수 있습니다. 회전 수를 사용자 정의할 수 있습니다. 여기에서 총 실행 수를 사용합니다. 계산 단계는 8의 배수여야 합니다. 예를 들어 매번 4번 회전해야 하는 경우 실행하는 기본 총 단계 수는 32단계이며 좌표를 기준으로 몇 단계를 수행해야 하는지 계산합니다. 백그라운드에 있는 선물에 경마가 실행하는 본부 수인 32를 더한 것입니다.처음에는 빠르고 나중에는 바쁩니다.타이머 setTimeout() 메서드를 사용하면 두 번째 매개 변수의 대기 시간이 길어지고 총 실행 단계 수가 정상 또는 2/3를 초과하면 타이머 대기 시간이 증가하여 다음 단계의 실행이 점점 느려지는 것으로 판단할 수 있습니다.

3단계: 백그라운드 추첨 결과

아이디어: 복권 결과가 백그라운드에서 반환되는 경우 인터페이스 오류 보고 및 긴 대기 시간과 같은 위에서 언급한 4번과 5번의 문제가 있을 수 있습니다. 애니메이션을 시작하기 전에 반환 결과를 요청하려면 클릭하고, 우리는 인터페이스 오류보고를 직접 프롬프트 할 수 있습니다. 오랜 시간 동안 기다리는 방법, 로딩 프롬프트를 추가하여 이 두 가지 문제를 기본적으로 해결할 수 있습니다. 애니메이션 효과의 실행 결과와 배경에서 반환된 결과를 어떻게 일치시킬 것인가에 대한 질문은 위에서 언급한 바와 같이 기본 실행 단계 수를 가지고 있으며 선물에 따라 몇 단계를 실행할지 계산합니다. 요청 결과의 좌표를 확인하고 일치하는 결과를 추가합니다.

코드
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style> * {margin: 0; padding: 0; box-sizing: border-box; }[v-cloak] {display: none;}.container {width: 450px;height: 450px;background: #98d3fc;border: 1px solid #98d3fc;margin: 100px auto;display: flex;flex-wrap: wrap;justify-content: space-around;align-items: center;}.item {width: 140px;height: 140px;border: 2px solid #fff;position: relative;}.item:nth-of-type(5) {cursor: pointer;}.item img {width: 100%;height: 100%;}.item p {width: 100%;height: 20px;background: rgba(0, 0, 0, 0.5);color: #fff;font-size: 12px;text-align: center;line-height: 20px;position: absolute;left: 0;bottom: 0;}.active {border: 2px solid red;box-shadow: 2px 2px 30px #fff;} </style>
</head>
<body><div id="app" v-cloak><div class="container"><div :class="['item', {'active': currentIndex === index}]"v-for="(item, index) in prizeList"@click="start(index)"><img :src="item.pic" alt=""><p v-if="index <img src="https://unpkg.com/vue@3/dist/vue.global.js"></script><script> const { createApp, onMounted, ref, reactive, toRefs, computed } = VuecreateApp({setup () {const state = reactive({prizeList: [{ name: '手机', pic: 'https://bkimg.cdn.bcebos.com/pic/3801213fb80e7bec54e7d237ad7eae389b504ec23d9e' },{ name: '手表', pic: 'https://img1.baidu.com/it/u=2631716577,1296460670&fm=253&fmt=auto&app=120&f=JPEG' },{ name: '苹果', pic: 'https://img2.baidu.com/it/u=2611478896,137965957&fm=253&fmt=auto&app=138&f=JPEG' },{ name: '棒棒糖', pic: 'https://img2.baidu.com/it/u=576980037,1655121105&fm=253&fmt=auto&app=138&f=PNG' },{ name: '娃娃', pic: 'https://img2.baidu.com/it/u=4075390137,3967712457&fm=253&fmt=auto&app=138&f=PNG' },{ name: '木马', pic: 'https://img1.baidu.com/it/u=2434318933,2727681086&fm=253&fmt=auto&app=120&f=JPEG' },{ name: '德芙', pic: 'https://img0.baidu.com/it/u=1378564582,2397555841&fm=253&fmt=auto&app=120&f=JPEG' },{ name: '玫瑰', pic: 'https://img1.baidu.com/it/u=1125656938,422247900&fm=253&fmt=auto&app=120&f=JPEG' }], // 后台配置的奖品数据currentIndex: 0, // 当前位置isRunning: false, // 是否正在抽奖speed: 10, // 抽奖转动速度timerIns: null, // 定时器实例currentRunCount: 0, // 已跑次数totalRunCount: 32, // 总共跑动次数 8的倍数prizeId: 0, // 中奖id})const startBtn = { name: '开始按钮', pic: 'https://img2.baidu.com/it/u=1497996119,382735686&fm=253' }// 奖品高亮顺序const prizeSort = [0, 1, 2, 5, 8, 7, 6, 3]// 要执行总步数const totalRunStep = computed(() => {return state.totalRunCount + prizeSort.indexOf(state.prizeId)})onMounted(() => {// state.prizeList.forEach((item, index) => {//item.id = index// })state.prizeList.splice(4, 0, startBtn)console.log(state.prizeList)})// 获取随机数const getRandomNum = () => {// const num = Math.floor(Math.random() * 9)// if (num === 4) {//console.log(">>>>>不能为4")//return getRandomNum()// } else {//return num // }// 这里一次必然可以取到 时间为1次return prizeSort[Math.floor(Math.random() * prizeSort.length)]}const start = (i) => {if (i === 4 && !state.isRunning) {// 重置数据state.currentRunCount = 0state.speed = 100state.isRunning = trueconsole.log('开始抽奖,后台请求中奖奖品')// 请求返回的奖品编号 这里使用随机数 但不能为4// const prizeId = getRandomNum()// console.log('中奖ID>>>', prizeId, state.prizeList[prizeId])// state.prizeId = prizeId// 模拟接口延时返回 如果接口突然报错如何处理?直接调用stopRun()方法停止转动setTimeout(() => {const prizeId = getRandomNum()console.log('中奖ID>>>', prizeId, state.prizeList[prizeId])state.prizeId = prizeId}, 2000)startRun()}}const startRun = () => {stopRun()console.log(state.currentRunCount, totalRunStep.value)// 要执行总步数// 已走步数超过if (state.currentRunCount > totalRunStep.value) {state.isRunning = falsereturn}state.currentIndex = prizeSort[state.currentRunCount % 8]// 如果当前步数超过了2/3则速度慢下来if (state.currentRunCount > Math.floor(state.totalRunCount * 2 / 3)) {state.speed = state.speed + Math.floor(state.currentRunCount / 3)console.log('速度>>>>', state.speed)}state.timerIns = setTimeout(() => {state.currentRunCount++startRun()}, state.speed)}const stopRun = () => {state.timerIns && clearTimeout(state.timerIns)}return {...toRefs(state),start}}}).mount('#app') </script" style="margin: auto" />
</body>
</html> 

마침내

HTML, CSS, JavaScript, HTTP, TCP 프로토콜, 브라우저, VUE, React, 데이터 구조 및 알고리즘, 총 201개의 인터뷰 질문을 포함하는 "프론트 엔드 제조업체 인터뷰 모음"을 구성하고 각 질문에 대한 답변 작성 질문 답변 및 분석.

도움이 필요한 친구들은 기사 끝에 있는 카드를 클릭하여 이 문서를 받고 무료로 공유할 수 있습니다.

문서의 일부는 다음을 보여줍니다.



기사의 길이가 제한되어 있으며 다음 내용은 하나씩 표시되지 않습니다.

도움이 필요한 친구는 아래 카드를 클릭하여 무료로 얻을 수 있습니다.

рекомендация

отblog.csdn.net/web22050702/article/details/128715834