Day 06 實現自訂義牌堆
今日目標 研究如何製作牌堆 製作牌堆 製作CardBox元件負責用來擺放卡片的容器,所以結構上就只是比原本卡片元件的稍寬,所以設計成可放子元件進去的樣板,然後當沒放牌時會產生跟牌一個寬高的隱藏區塊到slot裡面。 // CardBox.vue <template > <div class="card-box"> <slot> <div class="card" style="visibility: hidden;"></div> </slot> </div> </template> 所以目前首頁是長這樣,放了兩個空的CardBox佔位置。 // HomeView.vue <div style="display: grid; grid-template-columns: 1fr 1fr;"> <CardBox></CardBox> <CardBox></CardBox> </div> 接著思考如何實作卡牌從A點發到B點,看著畫面思考發現, 不如今天就來實作兩邊卡堆點擊後會移動到對方卡堆的功能。 這邊為了簡單驗證想法,定義函數geneateDeck(5, true)生成五張卡牌依序是梅花A~5(設為開牌), 我預計實驗兩個卡堆,所以函數也就設計以下兩個非常相似的函數, 功用正是將卡堆的最後一張卡彈出,並推到另一個牌堆。 // HomeView.vue const fstCards = ref(geneateDeck(5, true)); const secondCards = ref([]); const moveCardFromAToB = () => { const card = fstCards.value.pop(); if (card === undefined) return; secondCards.value.push(card); }; const moveCardFromBToA = () => { const card = secondCards.value.pop(); if (card === undefined) return; fstCards.value.push(card); }; 在經過一番折騰,發現CardBox.vue應該要內部自帶Card元件, 由外面用slot的方式注入進去畫面反而不好寫版面,當然也有可能是我排版功力不夠,改由props傳入cards陣列,由外部HomeView.vue處理資料傳遞,但由CardBox.vue負責卡片的顯示。 所以可以看到以下CardBox.vue會判斷當前有牌沒牌渲染不同的樣式。 // CardBox.vue <script setup> import { computed } from 'vue'; import Card from '../components/Card.vue'; const { cards } = defineProps(['cards']); const isEmpty = computed(() => { return cards.length == 0; }); </script> <template > <div class="card card-box" :class="{ 'empty-card-box': isEmpty }"> <div v-if="isEmpty">沒牌啦</div> <div v-else class="card"> <Card v-for="(card, index) in cards" :key="card.value" :value="card.value" :isOpen="card.isOpen" /> </div> </div> </template> 遊戲大廳HomeView.vue負責處理資料的部分依舊如上,但樣板改成傳簡單的卡片陣列進到<CardBox /> ...