iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 10
1
Modern Web

[Vue] 使用 Quasar 輕鬆打造 Material 及 iOS 風格的響應式網站系列 第 10

[Day 10] Vue Quasar 打造 旅遊網站系列 6 - Cards (卡片)

  • 分享至 

  • xImage
  •  

GitHub

Demo

今日完成的畫面

https://ithelp.ithome.com.tw/upload/images/20181025/20111805TCc3G1FyFX.png

https://ithelp.ithome.com.tw/upload/images/20181025/20111805IXHwUO6S5S.png

首頁的第一個區塊做完了

今天就來做第二個區塊吧

先看看兩大家的頁面

https://ithelp.ithome.com.tw/upload/images/20181025/20111805Gs5KOijKtj.png
https://ithelp.ithome.com.tw/upload/images/20181025/20111805fT8CDA3UCz.png

這種卡片形式的元件,咱們Quasar也有

我們就直接開始吧

建立並引入第二個區塊

一樣在 src/pages/Index 底下建一個 SectionCards.vue 檔案,用來當我們的卡片區塊。

然後記得在Index.vue引入哦

引入後Index.vue會長這樣

<template>
  <q-page>
    <section-carousel/>
    <section-cards/>
  </q-page>
</template>

<style>
</style>

<script>
  import SectionCarousel from './SectionCarousel'
  import SectionCards from './SectionCards'
  export default {
    components: {
      SectionCarousel,
      SectionCards
    }
  }
</script>

區塊內版面規劃

目前版面規劃大概是:

大螢幕 (3)(3)(3)(3)

中螢幕 (6)(6)

小螢幕 (12)

這樣分配

就版型而言的頁面會長這樣

<template>   
  <div class="row">
      <div class="col-12"><b>本月最精選</b></div>
      
      <div class="col-lg-3 col-sm-6 col-xs-12">卡片一</div>
      <div class="col-lg-3 col-sm-6 col-xs-12">卡片二</div>
      <div class="col-lg-3 col-sm-6 col-xs-12">卡片三</div>
      <div class="col-lg-3 col-sm-6 col-xs-12">卡片四</div>
  </div>
</template>

https://ithelp.ithome.com.tw/upload/images/20181025/20111805a8Kf5tHVge.png

製作卡片

卡片上會有 地點評分照片 等等的內容,如果要在這邊做會讓版面變超亂的,而且這邊也會大量的重複用,所以直接把卡片也獨立成一個元件(component)!!

我們到src/components/下建立一個 LCard.vue (名稱可以自訂沒關係)

Cards

別忘記到 quasar.conf.js 引入卡片的元件

framework: {
  components: [
    'QCard',
    'QCardTitle',
    'QCardMain',
    'QCardMedia',
    'QCardSeparator',
    'QCardActions'
  ]
}

我的作法通常都是先看Quasar的範例,找到自己喜歡的就去找他gitHub的範例原始碼,再複製下來自己改成自己要的樣子。

<template>
  <q-card inline>
    <q-card-media>
      <img src="statics/bg1.JPG"/>
    </q-card-media>

    <q-card-title>
      <span>標題標題</span>
      <div slot="subtitle" class="q-mt-sm">
        <span class="q-mr-sm">999則評價</span> 
        <span>888人瀏覽</span>
      </div>
    </q-card-title>

    <q-card-main>

    </q-card-main>
  </q-card>
</template>

卡片主要分成三個部分

  • q-card-media 放照片影片的區塊
  • q-card-title 卡片的標題
  • q-card-main 卡片的主內容

進階一點還有

  • q-card-actions 用來放按鈕等等操作用區塊
  • q-card-separator 分隔線

這邊就先依幫個區塊放上文字來看看

記得回去SectionCards.vue引入我們的LCard.vue

//SectionCards.vue

<div class="col-lg-3 col-sm-6 col-xs-12">
  <l-card/>
</div>

//script

import LCard from 'src/components/LCard.vue'
export default {
  components:{
    LCard
  },
}

加上Icon

再來補上評分地標的Icon

這邊也是要用到 Icon + 文字

剛好可以拿我們之前做的 LIcon.vue 來用

引入之後完整的code會長這樣

<template>
  <q-card inline>
    <q-card-media>
      <img src="statics/bg1.JPG"/>
    </q-card-media>

    <q-card-title>
      <span>標題標題</span>
      <div slot="subtitle" class="q-mt-sm">
        <l-icon :icon="'fas fa-star'" :text="'5.0'" :color="'orange'" class="q-mr-md"/>
        <span class="q-mr-sm">999則評價</span> 
        <span>888人瀏覽</span>
      </div>
    </q-card-title>

    <q-card-main>
      <l-icon :icon="'fas fa-map-marker-alt'" :text="'台北市'" :color="'grey'" class="q-mr-md"/>
    </q-card-main>
  </q-card>
</template>

<script>
import LIcon from 'src/components/LIcon.vue'
export default {
  components:{
    LIcon
  }
}
</script>


https://ithelp.ithome.com.tw/upload/images/20181025/20111805rWAEtsmEPa.png

讓 LCard 的文字能從父元件帶入

我們就把剛剛的欄位都挖洞,讓他能從外面帶進來吧

<template>
  <q-card inline>
    <q-card-media>
      <img :src="image"/>
    </q-card-media>

    <q-card-title>
      <span>{{ title }}</span>
      <div slot="subtitle" class="q-mt-sm">
        <l-icon :icon="'fas fa-star'" :text="rate" :color="'orange'" class="q-mr-md"/>
        <span class="q-mr-sm">{{ comment }}則評價</span> 
        <span>{{ view }}人瀏覽</span>
      </div>
    </q-card-title>

    <q-card-main>
      <l-icon :icon="'fas fa-map-marker-alt'" :text="locate" :color="'grey'" class="q-mr-md"/>
    </q-card-main>
  </q-card>
</template>

<script>
import LIcon from 'src/components/LIcon.vue'
export default {
  props:{
    image: String,
    title: String,
    rate: String,
    comment: String,
    view: String,
    locate: String
  },
  components:{
    LIcon
  }
}
</script>

在 SectionCards 設置資料

先在script裡加上我們的靜態資料

這邊就給他一個區塊四筆資料吧

圖片就先借用我網美同學IG上的圖 (事先已取得同意)

data(){
    return{
      monthBestList:[
        { title:'和明織品文化館 HMTM' , rate: '4.8', comment: '99', view: '3621', locate: '台灣, 台南市' ,image:'https://instagram.ftpe8-4.fna.fbcdn.net/vp/dc86cba53aada051ef601547e929676c/5C67AD0F/t51.2885-15/e35/27891849_1884619055118044_7666637221746704384_n.jpg'},
        { title:'澎湖鯨魚洞' , rate: '4.6', comment: '75', view: '2643', locate: '台灣, 馬公市' ,image:'https://instagram.ftpe8-4.fna.fbcdn.net/vp/f93efc19ab7686509713585bf9187e12/5C53A410/t51.2885-15/e35/43140377_2151186321761409_76062690586049376_n.jpg'},
        { title:'石門班哨角休憩區' , rate: '4.5', comment: '82', view: '2145', locate: '台灣, 馬公市' ,image:'https://instagram.ftpe8-4.fna.fbcdn.net/vp/2d264f50ef332891546137642b8b8b3c/5C802CF9/t51.2885-15/e35/37415020_1342680469168149_7997842370647293952_n.jpg'},
        { title:'宜蘭伯朗大道' , rate: '4.2', comment: '43', view: '1456', locate: '台灣, 宜蘭縣' ,image:'https://instagram.ftpe8-4.fna.fbcdn.net/vp/eb77236c054f378313665c25a5d1363b/5C509EB8/t51.2885-15/e35/35177408_443518052759652_8108135769303941120_n.jpg'},
      ]
    }
  }

然後我們上面的code就能用v-for直接產生多張卡片了

   <template v-for="(data,idx) in monthBestList">
      <div class="col-lg-3 col-sm-6 col-xs-12" :key="idx">
        <l-card 
          :title="data.title"
          :rate ="data.rate"
          :comment="data.comment"
          :view="data.view"
          :locate="data.locate"
          :image="data.image"
        />
      </div>
    </template>

調整CSS 及 layout

再來用CSS以及CSS Spacing Classes修飾一下就大功告成啦

SectionCards.vue

<template>   
  //這裡給他class section-card 並用 q-ma-sm 調整與四周間距
  <div class="row section-card q-ma-sm"> 
  
    //標題文字原本太小 也給他個 title 等等調整  
   	// 這裡用q-pa-sm來跟下方的卡片排版對齊
    <div class="col-12 q-pa-sm"><b class="title">本月最精選</b></div>
         
    <template v-for="(data,idx) in monthBestList">
    
     //div一樣用 q-pa-sm  看起來才不會太擠
      <div class="col-lg-3 col-sm-6 col-xs-12 q-pa-sm" :key="idx">
      
        <l-card 
          :title="data.title"
          :rate ="data.rate"
          :comment="data.comment"
          :view="data.view"
          :locate="data.locate"
          :image="data.image"
        />
      </div>
    </template>
  </div>
</template>

<style lang="stylus">
.section-card
  //一樣修正卡片離頁面左右邊緣的間距
  margin-right 5%
  margin-left 5%

  .title
    //讓 本月最精選 的字大一點
    font-size 24px
    
  //以下是修正LCard裡的q-card元件的CSS
  //至於為什麼在外面改,因為這樣能讓LCard在其他地方能有更多變化
  .q-card-title
    font-size 16px
    line-height 24px

  .q-card-media
    max-height 200px
</style>

那今天有修改的地方差不多這樣啦

今日改到的完整程式碼

src/pages/Index/Index.vue

<template>
  <q-page>
    <section-carousel/>
    <section-cards/>
  </q-page>
</template>

<style>
</style>

<script>
  import SectionCarousel from './SectionCarousel'
  import SectionCards from './SectionCards'
  export default {
    components: {
      SectionCarousel,
      SectionCards
    }
  }
</script>

src/pages/Index/SectionCards.vue

<template>   
  <div class="row section-card q-ma-sm">
    <div class="col-12 q-pa-sm"><b class="title">本月最精選</b></div>
    <template v-for="(data,idx) in monthBestList">
      <div class="col-lg-3 col-sm-6 col-xs-12 q-pa-sm" :key="idx">
        <l-card 
          :title="data.title"
          :rate ="data.rate"
          :comment="data.comment"
          :view="data.view"
          :locate="data.locate"
          :image="data.image"
        />
      </div>
    </template>
  </div>
</template>

<script>
import LCard from 'src/components/LCard.vue'
export default {
  components:{
    LCard
  },
  data(){
    return{
      monthBestList:[
        { title:'和明織品文化館 HMTM' , rate: '4.8', comment: '99', view: '3621', locate: '台灣, 台南市' ,image:'https://instagram.ftpe8-4.fna.fbcdn.net/vp/dc86cba53aada051ef601547e929676c/5C67AD0F/t51.2885-15/e35/27891849_1884619055118044_7666637221746704384_n.jpg'},
        { title:'澎湖鯨魚洞' , rate: '4.6', comment: '75', view: '2643', locate: '台灣, 馬公市' ,image:'https://instagram.ftpe8-4.fna.fbcdn.net/vp/f93efc19ab7686509713585bf9187e12/5C53A410/t51.2885-15/e35/43140377_2151186321761409_76062690586049376_n.jpg'},
        { title:'石門班哨角休憩區' , rate: '4.5', comment: '82', view: '2145', locate: '台灣, 馬公市' ,image:'https://instagram.ftpe8-4.fna.fbcdn.net/vp/2d264f50ef332891546137642b8b8b3c/5C802CF9/t51.2885-15/e35/37415020_1342680469168149_7997842370647293952_n.jpg'},
        { title:'宜蘭伯朗大道' , rate: '4.2', comment: '43', view: '1456', locate: '台灣, 宜蘭縣' ,image:'https://instagram.ftpe8-4.fna.fbcdn.net/vp/eb77236c054f378313665c25a5d1363b/5C509EB8/t51.2885-15/e35/35177408_443518052759652_8108135769303941120_n.jpg'},
      ]
    }
  }
}
</script>

<style lang="stylus">
.section-card
  margin-right 5%
  margin-left 5%

  .title
    font-size 24px

  .q-card-title
    font-size 16px
    line-height 24px

  .q-card-media
    max-height 200px
</style>

src/components/LCard.vue

<template>
  <q-card inline>
    <q-card-media>
      <img :src="image"/>
    </q-card-media>

    <q-card-title>
      <span>{{ title }}</span>
      <div slot="subtitle" class="q-mt-sm">
        <l-icon :icon="'fas fa-star'" :text="rate" :color="'orange'" class="q-mr-md"/>
        <span class="q-mr-sm">{{ comment }}則評價</span> 
        <span>{{ view }}人瀏覽</span>
      </div>
    </q-card-title>

    <q-card-main>
      <l-icon :icon="'fas fa-map-marker-alt'" :text="locate" :color="'grey'" class="q-mr-md"/>
    </q-card-main>
  </q-card>
</template>

<script>
import LIcon from 'src/components/LIcon.vue'
export default {
  props:{
    image: String,
    title: String,
    rate: String,
    comment: String,
    view: String,
    locate: String
  },
  components:{
    LIcon
  }
}
</script>


上一篇
[Day 9] Vue Quasar 打造 旅遊網站系列 5- Popover (彈出視窗)
下一篇
[Day 11] Vue Quasar 打造 旅遊網站系列 7 - Parallax、Breadcrumbs、Rating
系列文
[Vue] 使用 Quasar 輕鬆打造 Material 及 iOS 風格的響應式網站30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言