項目vue2.0仿外賣APP(五)

header組件

vue-resourse應用

https://github.com/pagekit/vue-resourcecss

vue-resource是Vue.js的一款插件,它能夠經過XMLHttpRequest或JSONP發起請求並處理響應。也就是說,$.ajax能作的事情,vue-resource插件同樣也能作到,並且vue-resource的API更爲簡潔。另外,vue-resource還提供了很是有用的inteceptor功能,使用inteceptor能夠在請求前和請求後附加一些行爲,好比使用inteceptor在ajax請求時顯示loading界面。html

vue-resource插件具備如下特色:vue

1. 體積小
vue-resource很是小巧,在壓縮之後只有大約12KB,服務端啓用gzip壓縮後只有4.5KB大小,這遠比jQuery的體積要小得多。
2. 支持主流的瀏覽器
和Vue.js同樣,vue-resource除了不支持IE 9如下的瀏覽器,其餘主流的瀏覽器都支持。
3. 支持Promise API和URI Templates
Promise是ES6的特性,Promise的中文含義爲「先知」,Promise對象用於異步計算。
URI Templates表示URI模板,有些相似於ASP.NET MVC的路由模板。
4. 支持攔截器
攔截器是全局的,攔截器能夠在請求發送前和發送請求後作一些處理。
攔截器在一些場景下會很是有用,好比請求發送前在headers中設置access_token,或者在請求失敗時,提供共通的處理方式。git

http://www.cnblogs.com/keepfool/p/5657065.htmlgithub

Header組件:商家數據,經過異步請求後端的數據接口得到的,header組件就負責接受這樣的數據並渲染 。那咱們就能夠在app.vue組件(header的父組件),經過發送一個AJAX請求去獲取商家的相關數據,而後把這些數據經過headerprop屬性傳遞給這個組件。ajax

能夠查看:http://cn.vuejs.org/v2/guide/components.html#example-2-5json

父子組件間的通訊segmentfault

組件意味着協同工做,一般父子組件會是這樣的關係:組件 A 在它的模版中使用了組件 B 。它們之間必然須要相互通訊:父組件要給子組件傳遞數據,子組件須要將它內部發生的事情告知給父組件。然而,在一個良好定義的接口中儘量將父子組件解耦是很重要的。這保證了每一個組件能夠在相對隔離的環境中書寫和理解,也大幅提升了組件的可維護性和可重用性。後端

Vue.js 中,父子組件的關係能夠總結爲 props down, events up 。父組件經過 props 向下傳遞數據給子組件,子組件經過 events 給父組件發送消息。看看它們是怎麼工做的。api


使用 Prop 傳遞數據

組件實例的做用域是孤立的。這意味着不能而且不該該在子組件的模板內直接引用父組件的數據。可使用 props 把數據傳給子組件。
prop 是父組件用來傳遞數據的一個自定義屬性。子組件須要顯式地用 props 選項聲明 「prop」:

Vue.component('child', {
  // 聲明 props
  props: ['message'],
  // 就像 data 同樣,prop 能夠用在模板內
  // 一樣也能夠在 vm 實例中像 「this.message」 這樣使用
  template: '<span>{{ message }}</span>'
})

而後向它傳入一個普通字符串:

<child message="hello!"></child>

結果輸出「hello」。

回到項目中來

首先咱們須要給app.vue定義一個seller的對象:能夠經過data()方法。在vue.js中,這個data屬性是一個函數(可查看連接),由於組件是能夠被複用的,若是定義一個對象而後修改某一個組件的話會影響另外的組件,因此這裏定義成一個函數。這個函數return一個對象,對象裏面有seller對象,先定爲空,而後咱們經過發送AJAX請求去拿到一個seller對象,而後send給它。這樣就能夠拿到seller對象的數據。

Vue.js社區有個第三方插件:vue-resource,用來處理一些先後端請求數據交互的。

示例:

{
  // GET /someUrl
  this.$http.get('/someUrl').then((response) => {
    // success callback
  }, (response) => {
    // error callback
  });
}

一樣的,在package.json添加它的依賴:

第三方插件import引用時須要註冊,用Vue.use(vueResource)把這個註冊。在main.js註冊

而後回到app.vue,在這裏咱們須要經過一個vue.resource去發送一個AJAX請求,須要在什麼時序去發起呢?

咱們知道每一個vue實例化的時候都有一個生命週期,其中有個鉤子叫created().

關於鉤子:https://segmentfault.com/q/1010000004335505

關於實例的生命週期:https://cn.vuejs.org/v2/guide/instance.html#實例生命週期 

這是它的一個生命週期鉤子函數,就是一個vue實例被生成後調用這個函數。一個vue實例被生成後還要綁定到某個html元素上,以後還要進行編譯,而後再插入到document中。每個階段都會有一個鉤子函數,方便開發者在不一樣階段處理不一樣邏輯。通常能夠在created函數中調用ajax獲取頁面初始化所需的數據。

 

可以看到這裏已經發送了:

還有不少字段:每一個字段都有getset方法:

到這vue-resource就介紹完了,seller對象已經拿到,接下來就把seller對象傳遞給header組件,讓header渲染便可。

 

外部組件

vue2.0組件間通訊:http://blog.csdn.net/qq_24122593/article/details/53509229

上一講從後端的seller API得到這個seller對象,如今就來把這個seller對象傳給header組件

https://cn.vuejs.org/v2/api/#props

經過v-bind指令去傳,把這個seller這個變量傳給這個header組件。

咱們在header組件裏面就會經過propS屬性去接受傳過來的seller

有了這個變量就能夠來寫它的DOM結構了。

<img width="64" height="64" src="seller.avatar">

這樣不行,不能直接指定src。須要用v-bind,這樣才能夠去引用頭像圖片的地址,由於seller.avatar一開始是不存在的

再寫寫樣式

有的層之間會有空隙,須要怎麼處理呢?方法有不少,這裏使用font-size。能夠先把父級的font-size設爲0,再設置自己的font-size

圖片的2x3x是對應不一樣的dpr的。須要用到媒體查詢,代碼比較多,寫在mixin.styl

減價、打折、特價等圖標須要根據後臺返回的數據來選擇,因此這裏就得根據後臺返回的數據修改class,這是須要動態綁定

爲了將它的數值對應到各自的含義,能夠定義一個classMap:

而後再動態添加class的值:

想要變化:減價變成特價。能夠去後臺該數據的順序:

接下來寫右下角的「5」:

<i class="icon-keyboard_arrow_right"></i>

這個小圖標用到的是字體圖標。

 

關於公告區:

爲了清除間隙還有不影響省略號,咱們就不用font-size0了,用其餘方法,就是元素緊貼一塊兒。

設置對齊的時候,能夠先設置頂部對齊:vertical-align: top,再進行調整

 

背景圖:

Image標籤設置它的容器的filter

背景置於容器的頂部:

position: absolute
top: 0
left: 0
z-index: -1

接下來:內部彈層詳細頁

要求:全屏、模糊、底部還有關閉按鈕,並且,高度可能比手機高度還高,這是就會有滾動條。

關閉按鈕在最下方,若是用普通的佈局的話,就會蓋在文字上面,這顯然不行。這時就要用到css striky footers佈局。相對窗口作fixed佈局

最外層:

.detail
      position: fixed
      z-index: 100
      top: 0
      left: 0
      width: 100%
      height: 100%
      overflow: auto
      background: rgba(7,17,27,0.5)

控制顯示和隱藏,在vue裏面能夠經過v-show指令去控制,還要給vue的實例裏面加一個選項data,它是一個function,由於可能會有多個實例組件。這個functionreturn一個object,會去跟蹤依賴一些變量。

data() {
      return {
        detailShow: false
      };
},

也就是說,咱們在new這個vue的時候,它會對data裏面的變量去編譯而後給它添加gettersetter,這樣當咱們的變量變化的時候,DOM就會跟着變化。

查看元素:

這是就要添加方法了:

showDetail() {
        this.detailShow = true;
      },

也就是說當咱們去點擊這個層的時候,會調用這個方法去改變detailShow,因爲這個變量是依賴跟蹤的,他就會訪問到data裏的detailShow,變化的時候vue也能夠檢測到,最後會通知這個DOM的指令,而後更新狀態。

就是這樣,用過vue去操做數據,從而改變DOM的狀態,這過程咱們並無去操做DOM

 

接下來寫詳情頁裏面的內容了,佈局是個問題

講一下sticky footershttp://www.tuicool.com/articles/rEbQjaM

Sticky footers能夠歸納以下:若是頁面內容不夠長的時候,頁腳塊粘貼在視窗底部;若是內容足夠長時,頁腳塊會被內容向下推送。

有不少種方案,這裏做者介紹一種比較複雜的可是兼容性好的方案。

定兩層,上一層要清除浮動:

最終套路:

detail-wrapper層要讓它的最小高度撐滿整個屏幕的,按鈕纔會定在最下面。內容層有個padding-bottom,關閉層有個margin-top,就是爲了向上提。

還要在base.styl添加清楚浮動的代碼。

detail-main是內容區塊,向上須要有margin-top,向下有padding-bottom

detail-close也是用到圖標字體,這裏還有一個重要的點:相對定位,而後向上的負margin-top,還要清除浮動。無論內容再多,關閉按鈕仍然可以定在底部,padding-bottom很關鍵。

 

接下來添加內容

不可能這樣整張圖吧,由於若是評分多的話,有100分呢,那麼這樣的圖片不得有上百行。並且項目也多處有星星,因此這樣能夠弄一個組件star.vue。並且把圖片都單獨切開,這樣無論什麼狀態都只有這麼多圖片。

爲了有更好的擴展性,而且足夠靈活,咱們要利用vue裏面的v-for的指令,根據咱們定的星星個數去遍歷它。

而且,因爲這裏的star有不一樣尺寸,因此也有不一樣樣式,因此就用一個v-bind綁定class

首先,star有不一樣的尺寸,這個尺寸的大小是由外部數據傳進來的,因此須要對外提供接口,能夠傳過來變量,告訴你star的尺寸是多少,得分又是多少。

這個過程主要仍是兩方面:根據得分給星星,星星尺寸也不一樣。

這裏還須要一個公式來根據傳過來的尺寸分數映射一個類型。

 

就好比傳進來的size是24,那麼計算以後就獲得star-24,這是就能夠設置size-24的相關樣式了。

再添加不一樣類型尺寸的star的樣式。

 

接下來就是star的遍歷了,它是一個數組,要得出須要多少個star。取整再除2,再取整數部分和小數部分。

由於半星只會有一個,因此只需一次push

長度不到5就補全。

itemClasses() {
        let result = [];
        let score = Math.floor(this.score * 2) / 2;
        let hasDecimal = score % 1 !== 0;
        let integer = Math.floor(score);
        for (let i = 0; i < integer; i++) {
          result.push(CLS_ON);
        }
        if (hasDecimal) {
          result.push(CLS_HALF);
        }
        while (result.length < LENGTH) {
          result.push(CLS_OFF);
        }
        return result;
      }

接下來回到header組件去引入了,而後註冊。註冊以後就能夠在DOM用這個標籤了。

Star標籤它是要傳兩個參數的。

Tract-byhttps://segmentfault.com/q/1010000005143763

查看元素:

還要在header.vue組件中設置他們的樣式,好比邊距什麼的,固然不能放在組件裏面,若是這樣就受限了。咱們能夠在在外層去包裝它的容器,而後在定義它的內邊距啊、高度等等

 

優惠公告:

這也是一個經典的佈局問題:線的寬度是自適應,文字居中。文字與線之間的空隙也要有半透明的背景,這裏會用移動端常見的佈局flex。

Flex佈局:http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html?utm_source=tuicool

通常有兩層,父元素displayflex子元素指定flex

這裏爲何子元素用div呢?由於用span的話在Android某些瀏覽器會有問題。

 

 

關於代碼中CSS的樣式兼容問題:咱們並沒有需所有寫出,由於有工具幫忙完成:

接下來寫優惠信息詳細內容:

這塊內容跟咱們外層的.support是類似的。

可是vue2.0中的index這樣用,請查看:http://cn.vuejs.org/v2/guide/list.html#v-for

接下來再添加詳細介紹,添加按鈕的關閉功能。

還能夠添加動畫,我還沒添加。

https://vuefe.cn/v2/guide/migration.html#過渡

https://segmentfault.com/q/1010000007738500

還有一點就是:在設計稿上能夠看到,它的背景是模糊的,和剛剛圖片模糊是徹底不同的。這個模糊只有在IOS上才能實現,它的實現是經過一個backdrop-filter: blur(10px)

 

下一張就到了商品這個組件了,這個組件纔是大大發揮vue的優點。

相關文章
相關標籤/搜索