免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
一起學(xué)Vue自定義組件之拼圖小游戲

通過學(xué)習(xí)Vue自定義組件,可以開發(fā)一些小功能,自娛自樂,鞏固學(xué)習(xí)的基礎(chǔ)知識(shí),本文以一個(gè)簡單的拼圖小游戲的例子,簡述Vue自定義組件的開發(fā),調(diào)用等基本流程,僅供學(xué)習(xí)分享使用,如有不足之處,還請(qǐng)指正。

涉及知識(shí)點(diǎn)

關(guān)于Vue組件的基礎(chǔ)知識(shí),前篇已有介紹,本例涉及知識(shí)點(diǎn)如下:

  • 拼圖游戲,只有相鄰的元素才可以交換位置,那如何判斷兩個(gè)元素相鄰,方法如下:

    • 左右相鄰:y軸坐標(biāo)相同,x軸相減的絕對(duì)值等于一個(gè)元素的寬度。

    • 上下相鄰:x軸坐標(biāo)相同,y軸相減的絕對(duì)值等于一個(gè)元素的高度。

  • 如何判斷拼圖中的可以與之交換位置的空白,方法如下:

    • 通過ref引用屬性,將空白屬性,定義為empty,其他定義為block,以便區(qū)分。

  • 如何將一張圖放到每一個(gè)元素上,并只顯示一塊內(nèi)容,方法如下:

    • 將背景圖的位置和元素的坐標(biāo)起始位置關(guān)聯(lián)起來,即將圖片的向左上方平移即可。

  • 元素之間的切換平滑過渡。在本例中,通過css樣式設(shè)置,所有元素的移動(dòng)都在0.3s內(nèi)完成,達(dá)到平滑過渡的效果。

示例效果圖

本例中拼圖游戲一共分5關(guān),分別是3*3,4*4等,難度逐級(jí)增加,所用圖片的均是500px*500px大小,如下圖所示:

當(dāng)拼圖完成時(shí),詢問是否進(jìn)行下一關(guān),如下所示:

下一關(guān),效果如下所示:

其他效果圖類似,只是分的行和列遞增,拼圖難度增加,但是處理邏輯都是相同的。

核心源碼

關(guān)于Puzzle.vue源碼,如下所示:

模板部分(template),主要是元素的布局,本例采用v-for動(dòng)態(tài)加載,如下所示:

 1 <template> 2   <div class="puzzle" :style="{width:width+'px',height:height+'px'}"> 3     <div 4       v-for="(item,index) in blockPoints" 5       :key="item.id" 6       :style="{width:blockWidth+'px', 7         height:blockHeight+'px', 8         left:item.x+'px',top:item.y+'px', 9         backgroundImage:`url(${img})`,10         backgroundPosition:`-${correctPoints[index].x}px -${correctPoints[index].y}px`,11         opacity: index===blockPoints.length-1 && 0 }"12       v-on:click="handleClick"13       class="puzzle__block"14       :ref="index===blockPoints.length-1?'empty':'block'"15       :data-correctX="correctPoints[index].x"16       :data-correctY="correctPoints[index].y"17     ></div>18   </div>19 </template>
View Code

腳本部分(Script),主要用于邏輯的校驗(yàn)和判斷,如下所示:

  1 <script>  2 export default {  3   props: {  4     img: {  5       // 圖片路徑  6       type: String,  7       required: true,  8     },  9     width: { 10       // 圖片總寬度 11       type: Number, 12       default: 500, 13     }, 14     height: { 15       // 圖片總高度 16       type: Number, 17       default: 500, 18     }, 19     row: { 20       // 行數(shù) 21       type: Number, 22       default: 3, 23     }, 24     col: { 25       // 列數(shù) 26       type: Number, 27       default: 3, 28     }, 29   }, 30   data() { 31     return { 32       status: { 33         type: String, 34         default: "進(jìn)行中......", 35       }, 36     }; 37   }, 38   methods: { 39     handleClick(e) { 40       const blockDom = e.target; 41       const empthDom = this.$refs.empty[0]; 42       const { left, top } = blockDom.style; 43       if (!this.isAdjacent(blockDom, empthDom)) { 44         return; 45       } 46       //交換元素 47       blockDom.style.left = empthDom.style.left; 48       blockDom.style.top = empthDom.style.top; 49       empthDom.style.left = left; 50       empthDom.style.top = top; 51       const winFlag = this.winCheck(); 52       if (winFlag) { 53         //   console.log('success'); 54         this.winGame(empthDom); 55       } 56     }, 57     isAdjacent(blockDom, empthDom) { 58       // 判斷是否相鄰 59       const { left: blockLeft, top: blockTop, width, height } = blockDom.style; 60       const { left: emptyLeft, top: emptyTop } = empthDom.style; 61       const xDis = Math.floor( 62         Math.abs(parseFloat(blockLeft) - parseFloat(emptyLeft)) 63       ); 64       const yDis = Math.floor( 65         Math.abs(parseFloat(blockTop) - parseFloat(emptyTop)) 66       ); 67       const flag = 68         (blockLeft === emptyLeft && yDis === parseInt(height)) || 69         (blockTop === emptyTop && xDis === parseInt(width)); 70       console.log(flag); 71       return flag; 72     }, 73     winCheck() { 74       // 判斷是否完成 75       const blockDomArr = this.$refs.block; 76       return blockDomArr.every((dom) => { 77         const { left: domLeft, top: domTop } = dom.style; 78         const { correctx: correctX, correcty: correctY } = dom.dataset; 79         const flag = 80           parseInt(domLeft) === parseInt(correctX) && 81           parseInt(domTop) === parseInt(correctY); 82         return flag; 83       }); 84       // console.log(blockDomArr.length); 85     }, 86     winGame(empthDom) { 87       //通關(guān) 88       setTimeout(() => { 89         this.status = "勝利"; 90         alert("恭喜通關(guān)"); 91         empthDom.style.opacity = 1; 92         this.$emit("getStatus"); 93         setTimeout(() => { 94           this.goToNextLevel(); 95         }, 300); 96       }, 300); 97     }, 98     goToNextLevel() { 99       const answerFlag = window.confirm("現(xiàn)在進(jìn)行下一關(guān)么?");100       if (answerFlag) {101         this.status = "進(jìn)行中......";102         this.$emit("next");103       }104     },105   },106   computed: {107     blockWidth() {108       return this.width / this.col;109     },110     blockHeight() {111       return this.height / this.row;112     },113     correctPoints() {114       const { row, col, blockWidth, blockHeight } = this;115       const arr = [];116       for (let i = 0; i < row; i++) {117         for (let j = 0; j < col; j++) {118           arr.push({119             x: j * blockWidth,120             y: i * blockHeight,121             id: new Date().getTime() + Math.random() * 100,122           });123         }124       }125       return arr;126     },127     blockPoints() {128       const points = this.correctPoints;129       const length = points.length; //數(shù)組的長度130       const lastEle = points[length - 1]; //最后一個(gè)元素131       const newArr = [...points];132       newArr.length = length - 1;133       //打亂順序134       newArr.sort(() => Math.random() - 0.5);135       newArr.push(lastEle);136       return newArr;137     },138   },139 };140 </script>
View Code

樣式部分(Style),主要用于外觀樣式的設(shè)置,如下所示:

 1 <style> 2 .puzzle { 3   box-sizing: content-box; 4   border: 2px solid #cccccc; 5   position: relative; 6 } 7 .puzzle__block { 8   border: 1px solid #ffffff; 9   box-sizing: border-box;10   /* background-color: rebeccapurple; */11   position: absolute;12   transition: all 0.3s;13 }14 </style>
View Code

 拼圖組件的調(diào)用App.vue

首先組件需要引入和注冊,采用使用,如下所示:

 1 <script> 2 import puzzle from "./Puzzle"; 3 export default { 4   components: { 5     puzzle, 6   }, 7   data() { 8     return { 9       level: 0,10       puzzleConfig: [11         { img: "./img/001.jpg", row: 3, col: 3 },12         { img: "./img/002.jpg", row: 4, col: 4 },13         { img: "./img/003.jpg", row: 5, col: 5 },14         { img: "./img/004.jpg", row: 6, col: 6 },15         { img: "./img/005.jpg", row: 7, col: 7 },16       ],17       status: "進(jìn)行中......",18     };19   },20   methods: {21     handleNext() {22       console.log("next");23       this.status = this.$refs.dpuzzle.status;24       this.level++;25       if (this.level == this.puzzleConfig.length - 1) {26         const answerFlag = window.confirm("已經(jīng)是最后一關(guān)了,需要重新開始么?");27         if (answerFlag) {28           this.level = 0;29         }30       }31     },32     getStatus() {33       this.status = this.$refs.dpuzzle.status;34     },35   },36 };37 </script>
View Code

組件的調(diào)用,如下所示:

1 <template>2   <div>3     <h3>[拼圖游戲]當(dāng)前是第{{level+1}}關(guān),當(dāng)前狀態(tài)[{{status}}]</h3>4     <puzzle ref="dpuzzle" @getStatus="getStatus" @next="handleNext" v-bind="puzzleConfig[level]" />5     <!-- <button @click="handleNext" style="width:20px,height:20px" value="下一關(guān)">下一關(guān)</button> -->6   </div>7 </template>
View Code

 注意事項(xiàng):

如果獲取組件內(nèi)部的元素的值,在組件調(diào)用時(shí)采用ref屬性,然后獲取組件內(nèi)的data屬性值。

組件內(nèi)如果調(diào)用父組件的方法,本文采用觸發(fā)注冊事件的方式this.$emit("next");

如果需要學(xué)習(xí)參考源碼的朋友,可以點(diǎn)擊源碼鏈接進(jìn)行下載。

源碼鏈接

備注

浪淘沙令·簾外雨潺潺

作者:李煜【五代十國南唐后主】

簾外雨潺潺,春意闌珊。

羅衾不耐五更寒。

夢里不知身是客,一晌貪歡。

獨(dú)自莫憑欄,無限江山,別時(shí)容易見時(shí)難。

流水落花春去也,天上人間。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
循序漸進(jìn)VUE+Element 前端應(yīng)用開發(fā)(25)--- 各種界面組件的使用(1)
前端摸魚神器,一小時(shí)打卡下班!
前端動(dòng)畫必知必會(huì):React 和 Vue 都在用的 FLIP 思想實(shí)戰(zhàn)
得心應(yīng)用的Vue高級(jí)技巧
vue項(xiàng)目實(shí)戰(zhàn)經(jīng)驗(yàn)匯總
vue3 Ts 封裝全局函數(shù)式組件教程——確認(rèn)彈窗組件
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服