[鼠年全马] 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


<<:  JS 闭包(Closure) DAY63

>>:  通用标准–评估保证水平(Common Criteria – Evaluation Assurance Level)

Day 06 - MVC 与三层架构

在Web 开发中,MVC 与三层架构这两个名词会经常被人提及,很多人会将它们混为一谈,认为MVC 就...

Day19:[排序演算法]Bubble Sort - 气泡排序法

bubble sort的概念就是像泡泡一样 ,越大的数字会渐渐的往右边浮 比较相邻的元素 ,两两比...

<Day30> 投资小白的最後独白

接续前一天的下单之後,股票顺利的入手啦 !! 果然是以平盘价买到,但今天收盘时跌了0.1元 但没关系...

Day 14:AWS是什麽?30天从动漫/影视作品看AWS服务应用 -《云端情人》part1

2013年由Spike Jonze执导,《云端情人》作为科幻取向的作品, 意外有别於总是导致灾难毁灭...

Day 12 Docker的简单介绍

今天来讲 Docker,你可能会想说奇怪,为什麽会突然提到 Docker 呢? 为什麽会提到 Doc...