iT邦幫忙

0

[鼠年全馬] W37 - Vue出一個旅館預約平台(11)

這週接續上週進度
把真實資料餵進 SuccessCard.vue 囉~


#左側預約功能(接續)

真實資料需要用到預約POST API回傳的資料
所以我們先回到 ReservationCard.vue 來處理

#Step 7

先看一下回傳的結果格式:
https://ithelp.ithome.com.tw/upload/images/20200811/20118686rACy41SSRo.jpg
可以看到回傳資料分成3個部分

  • success: 是否有預約成功
  • room: 房間詳細資訊
  • booking: 預約成功資訊,如果預約多天就會是陣列

回傳的資訊我們可以這樣操作:

  • success 來控制是否開啟 [預約成功頁面]
  • booking 預約成功資訊呈現在 SuccessCard.vue

#Step 8

開啟 Reservation.vue 加上 isSuccess 來控制以及 bookingData 預約成功資訊
並且提供方法讓子層元件使用 $emit 來呼叫改變值

//Reservation.vue
export default {
  name: "Reservation",
  data: () => ({
    isSuccess: false, //判斷是否開啟預約成功頁面
    bookingData: {}, //預約成功資訊,預設空object
  }),
  methods: {
    //子層使用$emit呼叫setSuccess()改變isSuccess值
    setSuccess(bool) {
      this.isSuccess = bool;
    },
    //子層使用$emit呼叫setBooking()改變bookingData值
    setBooking(booking) {
      this.bookingData = booking;
    },
  },
  ...,
};

#Step 9

接著就可以用 v-if 指令來判斷要渲染 [預約功能頁] 還是 [預約成功頁]:

<div>
  <ReservationTop v-if="!isSuccess" />
  <SuccessTop v-if="isSuccess" />  
  <div>
    <div>
      <ReservationCard v-if="!isSuccess" />
      <SuccessCard v-if="isSuccess" />
    </div>
  </div>
</div>

這裡也可以改成用 v-else-if 或 v-else 喔!!
只是我個人習慣都用 v-if

#Step 10

<ReservationCard> 的部分要加上 v-on 指令將要改變值的 method 傳進去:

<ReservationCard
  @setSuccess="setSuccess"
  @setBooking="setBooking"
/>

#Step 11

接著開啟 ReservationCard.vue 的預約POST方法,在成功的區塊中加上 $emit 呼叫方法來改變值:

this.$http({...})
  .then((res) => {
    //$emit呼叫setSuccess並傳入success來改變父層isSuccess的值
    this.$emit("setSuccess", res.data.success);
    //$emit呼叫setBooking並傳入booking來改變父層bookingData的值
    this.$emit("setBooking", res.data.booking);
  })

完成後就可以看到預約成功之後頁面就會跳轉囉!!
gif已死QQ

#Step 12

接著把 bookingData 預約成功資訊 以及 room 房間資訊 傳入 <SuccessCard>:

//Reservation.vue
<SuccessCard v-if="isSuccess" :booking="bookingData" :room="room" />

並開啟 SuccessCard.vue 接收傳入的資料:

export default {
  name: "SuccessCard",
  props: ["bookingData", "room"],
};

這裡可以打開chrome的Vue開發工具來檢查看看資料是否有確實傳進來
https://ithelp.ithome.com.tw/upload/images/20200811/20118686qF6QfkSSCX.jpg

#Step 13

接著就可以將傳入的真實資料塞進去囉~
這裡要注意,API回傳的資訊沒有包含 平日或假日,於是我自己寫了判斷

使用 javascript 的原生方法 new Date().getDay() 來判斷星期數

  • 1 2 3 4 5 代表星期一到五(平日)
  • 0 6 代表星期日和星期六(假日)
new Date(item.date).getDay()

接著用到陣列的 filter 方法搭配 indexOf 去篩選平日或是假日,篩選完取得陣列長度就是平日或假日的天數
filter用法參考卡斯伯老師這篇文

//平日的天數計算
this.booking.filter(function(item) {
  return [1, 2, 3, 4, 5].indexOf(new Date(item.date).getDay()) > -1;
}).length;
//假日的天數計算
this.booking.filter(function(item) {
  return [0, 6].indexOf(new Date(item.date).getDay()) > -1;
}).length;

#Step 14

將計算的程式碼丟進 computedreturn 結果:

computed: {
  //平日天數
  normaldaynum() {
    return this.booking.filter(function(item) {
      return [1, 2, 3, 4, 5].indexOf(new Date(item.date).getDay()) > -1;
    }).length;
  },
  //假日天數
  holidaynum() {
    return this.booking.filter(function(item) {
      return [0, 6].indexOf(new Date(item.date).getDay()) > -1;
    }).length;
  },
},

#Step 15

困難的部份都完成了,剩下的就是簡單的資料對應替換而已
最後對應完長這樣:

<div class="main mt-10">
  <div class="successcard pt-4 pl-7 pr-8 pb-8">
    <div class="successcardtitle">預約成功!</div>
    <div class="mt-8">
      <span>姓名</span>
      <span class="pl-4">{{ booking[0].name }}</span>
    </div>
    <div class="mt-7">
      <span>電話</span>
      <span class="pl-4">{{ booking[0].tel }}</span>
    </div>
    <div class="mt-7">
      <span>日期</span>
    </div>
    <div v-if="normaldaynum > 0" class="mt-4 d-flex justify-space-between">
      <div><span>平日(一~五)</span></div>
      <div>
        <span>${{ room.normalDayPrice }}</span>
        <span class="ml-3 mr-3">x</span>
        <span>{{ normaldaynum }}晚</span>
      </div>
      <div>
        <span>${{ room.normalDayPrice * normaldaynum }}</span>
      </div>
    </div>
    <div v-if="holidaynum > 0" class="mt-4 d-flex justify-space-between">
      <div><span>假日(六~日)</span></div>
      <div>
        <span>${{ room.holidayPrice }}</span>
        <span class="ml-3 mr-3">x</span>
        <span>{{ holidaynum }}晚</span>
      </div>
      <div>
        <span>${{ room.holidayPrice * holidaynum }}</span>
      </div>
    </div>
    <v-divider class="mt-3" color="#A5BB94"></v-divider>
    <div class="mt-4">
      <span
        >${{
          normaldaynum * room.normalDayPrice + holidaynum * room.holidayPrice
        }}</span
      >
    </div>
  </div>
  <div class="successalert mt-3 pt-3 pl-10 pr-10 pb-4">
    <div><span>提醒!</span></div>
    <div class="d-flex justify-space-between">
      <div>
        <div><span>checkIn 時間</span></div>
        <div>
          <span class="alertvalue"
            >{{ room.checkInAndOut.checkInEarly }}~{{
              room.checkInAndOut.checkInLate
            }}</span
          >
        </div>
      </div>
      <div>
        <div><span>最晚checkout 時間</span></div>
        <div>
          <span class="alertvalue">{{ room.checkInAndOut.checkOut }}</span>
        </div>
      </div>
    </div>
  </div>
</div>

#結果

來看看整個做完之後的畫面吧~(因為影片長度太長被切成兩部份 哈哈)
gif已死QQ
gif已死QQ


到這邊 旅館預約平台 專案算是告一段落了~
花了11週完成它,過程中也學到很多的之前沒用過的方法,獲益良多,果然程式要實際寫才會進步~/images/emoticon/emoticon01.gif

仔細看的話可以發現還蠻多待改進的地方
像是 沒有過度動畫、預約失敗沒有回饋 等等的小地方
有機會再回來完善它xD

附上這次進度的雲端壓縮檔, 執行前記得先npm install

有需要改進或是任何意見建議歡迎下面留言~

下一篇主題,還沒想到 哈哈哈~/images/emoticon/emoticon07.gif/images/emoticon/emoticon07.gif/images/emoticon/emoticon07.gif


尚未有邦友留言

立即登入留言