iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 9
1
Modern Web

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

[Day 9] Vue Quasar 打造 旅遊網站系列 5- Popover (彈出視窗)

今天做完我們的頁面會長這樣~
https://ithelp.ithome.com.tw/upload/images/20181023/20111805g25sJzkYin.png

https://ithelp.ithome.com.tw/upload/images/20181024/201118056K4GnibrKY.png

今天一樣接續昨天的部分~

我們來做搜尋點擊但是還沒輸入時下面出現的視窗

https://ithelp.ithome.com.tw/upload/images/20181024/20111805FddwPVXTws.png

https://ithelp.ithome.com.tw/upload/images/20181024/20111805Hv62cCjW7z.png

KLOOK 的視窗雖然有圖片美觀,本來也想做像這種的

但是他的響應式沒做得太好,在中間的解析度看會悲劇...

畢竟有圖片的排版要做RWD要多花許多工

所以我們還是像 KKDAY 做文字版的就好

加入Popover元件

Popover

這個元件原來就是當作點擊按鈕時的彈出視窗

只是我們這邊讓他變得大一點 XDD

一樣也是去 quasar.conf.js 引入喔

如果又要用到v-close-overlay可以多引入底下的,但這邊我們暫且用不到

framework: {
  components: ['QPopover'],

  // optional if you want to use
  // directive `v-close-overlay`
  directives: ['CloseOverlay']
}

跟昨天的自動完成(Autocomplete)一樣要包在 q-input 裡面,才能在點擊框框時自動跳出來

<q-popover
  no-focus
  fit
  v-show="!search"
>
</q-popover>

這裡我們設定一些屬性

  • no-focus

    不設焦點,這樣才能繼續在輸入框輸入文字。沒加這個設定會導致無法輸入,因為focus在我們這個元件上了~

  • fit

    使這個彈出框框跟我們的輸入框的長度等長,就不用再用其他方法去同步兩者的寬度

  • v-show="!search"

    search是我們在input裡做綁定當作輸入值的變數,這邊的用意是讓輸入匡一有文字輸入,就不顯示這個彈跳視窗。因為輸入框輸入後會產生Autocomplete的候選框,要避免兩個視窗有同時出現的情況。

內容排版

我們直接參考KKDAY的版型

一樣是分成左中右三個欄位

這邊一樣使用FlexCSS來做排版

<div class="row viewList">
  <div class="col-sm-4 col-xs-12"></div>
  <div class="col-sm-4 col-xs-12"></div>
  <div class="col-sm-4 col-xs-12"></div>
</div>

一樣要考慮到響應式排版喔~

原版大解析度是切成三欄(4,4,4)

在小解析度就要變成這樣

(12)

(12)

(12)

然後上面多給一個自訂的class viewList

並在CSS底下加入

  @media (max-width 576px)
    .viewList
      width 280px

用來解決在手機尺寸版型下 原本Popover不能自動fix的問題

*這邊應該是小於Popover的fix之最小寬度

所以在版型低於xs (576px)時讓他能夠更小

我們根據iPhone6/7/8的尺寸來做調整,把它設定 280px.

設定內容 (List & Item)

沒想到這麼快就又跟list見面啦~

List & Item

這邊列表類的直接用list來做最快了

直接塞進剛剛的 <div class="col-sm-4 col-xs-12">塞這裡</div>

先做一筆來看看

<q-list link no-border>
  <q-list-header>熱門目的地</q-list-header>
  <q-item>
    <q-item-main>
      東京 
    </q-item-main>
  </q-item>
</q-list>

https://ithelp.ithome.com.tw/upload/images/20181024/20111805jXzlMfzEAV.png

加入右側Icon及文字

加個icon跟文字可以讓介面更有感~那就來家吧

感覺這個icon+文字的組合以後可能有很多地方能用到

所以我們直接做成元件(component)

首先先在 src/components/ 底下建立我們的檔案

檔名...恩...就姑且起一個 開頭+元件名

我們就以L作為開頭,各位同學可以依照自己喜好更改

就叫 LIcon.vue

<template>
  <div class="layout" :style="{ color: color}">
    <q-icon :class="icon" />
    {{ text }}
  </div>
</template>

<script>
export default {
  props:{
    text: String,
    icon: String,
    color: String,
  }
}
</script>


<style lang="stylus" scoped>
  .layout
    display inline-block
    font-size 14px
</style>

主要是使用了 q-icon 來引入font-awesome的icon

再來在後面加入我們的文字,由於q-icon會自動換行,因此要用CSSdisplay:inline-block 讓元件不會換行

這裡設定了三個可以從父元件傳值進來的參數分別為 text(要顯示的字)iconcolor(要顯示的顏色)

在原本的頁面引入子元件

在原本頁面的script上加入剛剛做的元件

import LIcon from 'src/components/LIcon.vue'

記得要在components中跟他說你有引入了

  components:{
    LIcon
  },

接著就能加到我們剛剛 東京 的後面啦

把子元件剛剛能吃的值都餵給他吃~

東京 <l-icon :icon="'fab fa-gripfire'" :text="'Hot'" :color="'orange'"/>

現在看起來好很多呢

https://ithelp.ithome.com.tw/upload/images/20181024/20111805DrK8GSNpv7.png

填入更多欄位

既然分成三欄,我們就放個 '熱門目的地'、'國內'、'國外' 好了

再來就把資料複製貼過去就好囉

剛剛LIcon的值也可以自己再調整

今天就差不多大功告成囉

本次修改的程式碼

SectionCarousel.vue

<template>
  <q-carousel
    color="white"
    infinite
    arrows
    autoplay
    height="400px"
  >
    <q-carousel-slide img-src="statics/bg1.JPG" />
    <q-carousel-slide img-src="statics/bg2.JPG" />
    <q-carousel-control
      position="center"
      slot="control-nav" 
      slot-scope="carousel" 
      class="carouselInput"
    >
      <div class="main">
        <b class="title">孔子的中心思想是個仁</b>
        <p class="subtitle">仁的本性是</p>

        <div class="row"> 
          <div class="col-md-2 col-xs-1"></div>
          <div class="col-md-8 col-xs-10">
            <q-input
              inverted-light
              color="white"
              placeholder="輸入城市/景點 或是想去的地方"
              :after="[{
                icon:'fas fa-search-location'
              }]"
              v-model="search"
            >
                <q-autocomplete
                  :static-data="{field: 'label', list: countries}"
                  :filter="advFilter"
                />
                <q-popover
                  no-focus
                  fit
                  v-show="!search"
                >
                  <div class="row viewList">
                    <div class="col-sm-4 col-xs-12">
                      <q-list link no-border>
                        <q-list-header>熱門目的地</q-list-header>
                        <q-item>
                          <q-item-main>
                            東京 <l-icon :icon="'fab fa-gripfire'" :text="'Hot'" :color="'orange'"/>
                          </q-item-main>
                        </q-item>
                        <q-item>
                          <q-item-main>
                            大阪 <l-icon :icon="'fab fa-gripfire'" :text="'Hot'" :color="'orange'"/>
                          </q-item-main>
                        </q-item>
                        <q-item>
                          <q-item-main>
                            北海道 <l-icon :icon="'fas fa-cannabis'" :text="'秋楓限定'" :color="'#f44336'"/>
            
                          </q-item-main>
                        </q-item>
                        <q-item>
                          <q-item-main>
                            香港
                          </q-item-main>
                        </q-item>
                        <q-item>
                          <q-item-main>
                            西藏 
                          </q-item-main>
                        </q-item>
                      </q-list>
                    </div>
                    <div class="col-sm-4 col-xs-12">
                      <q-list link no-border>
                        <q-list-header>國內旅遊</q-list-header>
                        <q-item>
                          <q-item-main>
                            南投 <l-icon :icon="'fab fa-pagelines'" :text="'櫻花限定'" :color="'#f50057'"/>
                          </q-item-main>
                        </q-item>
                        <q-item>
                          <q-item-main>
                            太魯閣 <l-icon :icon="'fab fa-gripfire'" :text="'Hot'" :color="'orange'"/>
                          </q-item-main>
                        </q-item>
                        <q-item>
                          <q-item-main>
                            綠島 <l-icon :icon="'fab fa-gripfire'" :text="'Hot'" :color="'orange'"/>
                          </q-item-main>
                        </q-item>
                        <q-item>
                          <q-item-main>
                            蘭嶼 
                          </q-item-main>
                        </q-item>
                        <q-item>
                          <q-item-main>
                            小琉球 
                          </q-item-main>
                        </q-item>
                      </q-list>
                    </div>
                    <div class="col-sm-4 col-xs-12">
                      <q-list link no-border>
                        <q-list-header>海外地區</q-list-header>
                        <q-item>
                          <q-item-main>
                            加州 <l-icon :icon="'fab fa-gripfire'" :text="'Hot'" :color="'orange'"/>
                          </q-item-main>
                        </q-item>
                        <q-item>
                          <q-item-main>
                            雪梨 <l-icon :icon="'fab fa-gripfire'" :text="'Hot'" :color="'orange'"/>
                          </q-item-main>
                        </q-item>
                        <q-item>
                          <q-item-main>
                            里約
                          </q-item-main>
                        </q-item>
                        <q-item>
                          <q-item-main>
                            邁阿密 
                          </q-item-main>
                        </q-item>
                        <q-item>
                          <q-item-main>
                            巴黎 
                          </q-item-main>
                        </q-item>
                      </q-list>
                    </div>
                  </div>

               

                </q-popover>
            </q-input>
          </div>
          <div class="col-md-2 col-xs-1"></div>
        </div>

        
      </div>

    </q-carousel-control>
  </q-carousel>
</template>

<script>
import _ from 'lodash'
import LIcon from 'src/components/LIcon.vue'
export default {
  data()
  {
    return {
      search: '',
      countries: [
        { label:'台北市' , icon:'fas fa-map-marker-alt' },
        { label:'新北市' , icon:'fas fa-map-marker-alt' },
        { label:'台中市' , icon:'fas fa-map-marker-alt' },
        { label:'「網美景點」台中秋紅谷,秋季賞楓勝地', stamp:'台中市' },
        { label:'東京台場「獨角獸鋼彈」強勢來襲!精彩變身演出搶先看' , stamp:'東京, 台場', rightTextColor:'pink-13'}
      ]
    }
  },
  components:{
    LIcon
  },
  methods:{
    advFilter(terms , { field, list}) {
      return _.filter( list , context => {
        return context[field].match(terms)
      })
    }
  }
}
</script>


<style lang="stylus" scoped>
  .carouselInput 
    width 90%
  .carouselInput .main
    text-align center
    color white
  .carouselInput .main .search
    width 300px
  .imageWall
    width 100px
    height 100px
    object-fit cover


  @media (min-width 768px)
    .carouselInput .title
      font-size 48px
    .carouselInput .subtitle
      font-size 24px

  @media (max-width 768px)
    .carouselInput .title
      font-size 24px
    .carouselInput .subtitle
      font-size 16px

  @media (max-width 576px)
    .viewList
      width 280px
</style>


src/components/LInput.vue

<template>
  <div class="layout" :style="{ color: color}">
    <q-icon :class="icon" />
    {{ text }}
  </div>
</template>

<script>
export default {
  props:{
    text: String,
    icon: String,
    color: String,
  }
}
</script>


<style lang="stylus" scoped>
  .layout
    display inline-block
    font-size 14px
</style>


上一篇
[Day 8] Vue Quasar 打造 旅遊網站系列 4 - Input、Autocomplete
下一篇
[Day 10] Vue Quasar 打造 旅遊網站系列 6 - Cards (卡片)
系列文
[Vue] 使用 Quasar 輕鬆打造 Material 及 iOS 風格的響應式網站30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言