1-vuejs2.0實戰:仿豆瓣app項目,建立自定義組件tabbar

你們好,我給你們分享一下仿豆瓣app的教程。固然了,咱們不是用原生去實現,而是用前端框架vuejs來實現豆瓣app。————第一次寫文章,寫得很差請見諒。css

爲何咱們選擇豆瓣app 來作這樣一個教程?前端

是由於我很早就接觸豆瓣這個網站,我比較喜歡看豆瓣裏面電影和文章的點評。而且豆瓣提供了很是豐富的一個api接口供咱們使用。也就是說咱們能夠不經過後端,直接經過前端ajax來獲取電影和圖書的數據,來組裝咱們app。vue

咱們能夠看一下豆瓣app首頁是一個什麼樣子 gifwebpack

Paste_Image.png

以上就是豆瓣app的一個截圖。git

咱們先來分析一下github

首頁分爲四個部分。第一個就是頂部的搜索框。搜索框下面就是一個banner圖切換。在下面就是一些熱點的文章列表。最底部就是一個tab切換。在這篇教程中,咱們經過vue的組件來實現這樣一個首頁的佈局。web

        • *
          建立豆瓣項目ajax

咱們能夠經過官方vue-cli初始化項目,這裏咱們採用webpack示例vue-router

vue init webpack douban

填寫項目描述,做者,安裝vue-routervue-cli

? Project name douban
? Project description douban
? Author afei
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? No
? Setup unit tests with Karma + Mocha? No
? Setup e2e tests with Nightwatch? No

   vue-cli · Generated "douban".

   To get started:

     cd douban
     npm install
     npm run dev

   Documentation can be found at https://vuejs-templates.github.io/webpack

初始化後,經過npm install安裝依賴

cd douban
npm install

運行項目,能夠看到基於官方vue-cli的模版就建立好了

npm run dev

Paste_Image.png

將所須要用的資源,拷貝到項目中,這裏我經過解壓豆瓣app得到他的一些圖片素材,拷入到src/assets/images目錄裏。

css這裏我用到了normaliz.css

在src下,新建了一個pages目錄,存放每個頁面組件,能夠看一下咱們的目錄

Paste_Image.png

因爲咱們的首頁更改了位置,因此在router裏面的index.js須要更改成

import Vue from 'vue'
import Router from 'vue-router'
import Index from '../pages/Index'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Index',
      component: Index
    }
  ]
})

每個組件的css咱們經過less來編寫,全部須要經過npm安裝less插件

npm install less less-loader --save

使用less預處理器須要在頁面添加 lang='less'

<style scoped lang="less">
    
</style>

第一個組件 tabbar

如何建立自定義組件tabbar,也就是豆瓣app底部的工具欄。這裏的結構咱們參考了mint-ui

這是咱們將要實現的效果圖。

Paste_Image.png

咱們先來分析一下這個組件的結構。

這個組件分爲兩部分:第一個是組件的外層容器,第二個是組件的子容器item,子組件裏面又分爲圖片和文字組合。子組件有2個狀態,一個默認灰色的狀態,一個選中狀態,咱們來實現一下這個組件的佈局。在index.vue裏面

template

<div class="m-tabbar">
  <a class="m-tabbar-item is-active">
    <span class="m-tabbar-item-icon">
       < img src="../assets/images/ic_tab_home_normal.png" alt="">
    </span> 
    <span class="m-tabbar-item-text">  
          首頁
    </span>
  </a> 
  <a class="m-tabbar-item">
    <span class="m-tabbar-item-icon">
       < img src="../assets/images/ic_tab_subject_normal.png" alt="">
    </span> 
    <span class="m-tabbar-item-text">  
          書影音
    </span>
  </a> 
  <a class="m-tabbar-item">
    <span class="m-tabbar-item-icon">
       < img src="../assets/images/ic_tab_status_normal.png" alt="">
    </span> 
    <span class="m-tabbar-item-text">  
          廣播
    </span>
  </a> 
  <a class="m-tabbar-item">
    <span class="m-tabbar-item-icon">
       < img src="../assets/images/ic_tab_group_normal.png" alt="">
    </span> 
    <span class="m-tabbar-item-text">  
          小組
    </span>
  </a> 
  <a class="m-tabbar-item">
    <span class="m-tabbar-item-icon">
       < img src="../assets/images/ic_tab_profile_normal.png" alt="">
    </span> 
    <span class="m-tabbar-item-text">  
          個人
    </span>
  </a> 
</div>

style

<style lang="less">
.m-tabbar{
    display: flex;
    flex-direction: row;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    width: 100%;
    overflow: hidden;
    height: 50px;
    background: #fff;
    border-top: 1px solid #e4e4e4;
    
    .m-tabbar-item{
      flex: 1;
      text-align: center;
      .m-tabbar-item-icon{
          display: block;
          padding-top: 2px;
          img{
              width: 28px;
              height: 28px;
          }
      }
      .m-tabbar-item-text{
          display: block;
          font-size: 10px;
          color:#949494;
      }
      &.is-active{
          .m-tabbar-item-text{
              color: #42bd56;
          }
      }
  }
}
</style>

佈局大功告成~~~~

前面咱們說的是,經過組件的方式來實現這個app。

若是像上面代碼這樣的話確定是不行的!既然咱們大致佈局已經寫好了,如今就能夠經過組件的方式來調用。固然咱們還要改造一下代碼。

先在components文件夾下面,新建兩個組件,經過這兩個組件來組合實現咱們底部的tab組件:

一個是tabbar-item.vue,實現子組件的item項,

tabbar-item.vue

<template>
    <a class="m-tabbar-item" >
        <span class="m-tabbar-item-icon"><slot name="icon-normal"></slot></span>
        <span class="m-tabbar-item-text"><slot></slot></span>
    </a>
</template>

<style lang="less">
.m-tabbar-item{
    flex: 1;
    text-align: center;
    .m-tabbar-item-icon{
        display: block;
        padding-top: 2px;
        img{
            width: 28px;
            height: 28px;
        }

    }
    .m-tabbar-item-text{
        display: block;
        font-size: 10px;
        color:#949494;
    }
    &.is-active{
        .m-tabbar-item-text{
            color: #42bd56;
        }
    }
}
</style>

一個是tabbar.vue,實現tab的外層容器,

tabbar.vue

<template>
    <div class="m-tabbar">
       <slot></slot>
    </div>
</template>
<style lang="less">
.m-tabbar{
    display: flex;
    flex-direction: row;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    width: 100%;
    overflow: hidden;
    height: 50px;
    background: #fff;
    border-top: 1px solid #e4e4e4;
}
</style>

在Index.vue中組合這兩個組件,實現tab組件效果

<template>
  <div>
    <m-tabbar>
      <m-tabbar-item id='tab1'>
        < img src="../assets/images/ic_tab_home_normal.png" alt="" slot="icon-normal"> 
        首頁
      </m-tabbar-item>
      <m-tabbar-item id='tab2'>
        < img src="../assets/images/ic_tab_subject_normal.png" alt="" slot="icon-normal"> 
        書影音
      </m-tabbar-item>
      <m-tabbar-item id='tab3'>
        < img src="../assets/images/ic_tab_status_normal.png" alt="" slot="icon-normal"> 
        廣播
      </m-tabbar-item>
      <m-tabbar-item id='tab4'>
        ![](../assets/images/ic_tab_group_normal.png) 
        小組
      </m-tabbar-item>
       <m-tabbar-item id='tab5'>
        < img src="../assets/images/ic_tab_profile_normal.png" alt="" slot="icon-normal"> 
        個人
      </m-tabbar-item>
    </m-tabbar>
  </div>
</template>

<script>
  import mTabbar from '../components/tabbar'
  import mTabbarItem from '../components/tabbar-item'
  export default {
    name: 'index',
    components: {
      mTabbar,
      mTabbarItem
    }
  }
</script>

完成的效果。

Paste_Image.png

        • *

光有一個死的界面,沒有點擊切換的效果怎麼能行?

如下咱們經過vue使用自定義事件的表單輸入組件來實現點擊切換的效果。

        • *

先給Index.vue裏面的tab組件加上v-model 來進行數據雙向綁定,經過select來達到選擇item,在item裏面再添加一個選中的active圖片

<template>
  <div>
    測試
    <m-tabbar v-model="select">
      <m-tabbar-item id='tab1'>
        < img src="../assets/images/ic_tab_home_normal.png" alt="" slot="icon-normal"> 
        < img src="../assets/images/ic_tab_home_active.png" alt="" slot="icon-active"> 
        首頁
      </m-tabbar-item>
      <m-tabbar-item id='tab2'>
        < img src="../assets/images/ic_tab_subject_normal.png" alt="" slot="icon-normal"> 
        < img src="../assets/images/ic_tab_subject_active.png" alt="" slot="icon-active"> 
        書影音
      </m-tabbar-item>
      <m-tabbar-item id='tab3'>
        < img src="../assets/images/ic_tab_status_normal.png" alt="" slot="icon-normal"> 
        < img src="../assets/images/ic_tab_status_active.png" alt="" slot="icon-active"> 
        廣播
      </m-tabbar-item>
      <m-tabbar-item id='tab4'>
        < img src="../assets/images/ic_tab_group_normal.png" alt="" slot="icon-normal"> 
        < img src="../assets/images/ic_tab_group_active.png" alt="" slot="icon-normal"> 
        小組
      </m-tabbar-item>
       <m-tabbar-item id='tab5'>
        < img src="../assets/images/ic_tab_profile_normal.png" alt="" slot="icon-normal"> 
        < img src="../assets/images/ic_tab_profile_active.png" alt="" slot="icon-normal"> 
        個人
      </m-tabbar-item>
    </m-tabbar>
  </div>
</template>

<script>
  import mTabbar from '../components/tabbar'
  import mTabbarItem from '../components/tabbar-item'
  export default {
    name: 'index',
    components: {
      mTabbar,
      mTabbarItem
    },
    data() {
      return {
        select:"tab1"
      }
    }
  }
</script>

tabbar.vue裏面經過props來傳遞數據vaule

<template>
    <div class="m-tabbar">
       <slot></slot>
    </div>
</template>
<script>
    import mTabbarItem from './tabbar-item';
    export default {
        props: ['value']
    }
</script>
<style lang="less">
.m-tabbar{
    display: flex;
    flex-direction: row;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    width: 100%;
    overflow: hidden;
    height: 50px;
    background: #fff;
    border-top: 1px solid #e4e4e4;
}
</style>

tabbar-item.vue組件:根據父組件的value和當前組件的id判斷是否爲選中狀態,經過 $parent.$emit('input',id) - 觸發父組件的自定義事件,添加選中的圖片,根據isActive來顯示隱藏

<template>
    <a class="m-tabbar-item" :class="{'is-active':isActive}" @click="$parent.$emit('input',id)">
        <span class="m-tabbar-item-icon" v-show="!isActive"><slot name="icon-normal"></slot></span>
        <span class="m-tabbar-item-icon" v-show="isActive"><slot name="icon-active"></slot></span>
        <span class="m-tabbar-item-text"><slot></slot></span>
    </a>
</template>
<script>
    export default{
        props: ['id'],
        computed: {
           isActive(){
               if(this.$parent.value===this.id){
                   return true;
               }
           }
        }
    }
</script>
<style lang="less">
.m-tabbar-item{
    flex: 1;
    text-align: center;
    .m-tabbar-item-icon{
        display: block;
        padding-top: 2px;
        img{
            width: 28px;
            height: 28px;
        }

    }
    .m-tabbar-item-text{
        display: block;
        font-size: 10px;
        color:#949494;
    }
    &.is-active{
        .m-tabbar-item-text{
            color: #42bd56;
        }
    }
}
</style>

大功告成,tabbar組件就完成了~

錄像1_轉.gif

感謝餓了麼團隊給咱們帶來了這麼好的ui組件!

源碼下載 連接:http://pan.baidu.com/s/1qYlR8g0 密碼:9yph

下載安裝

npm install
npm run dev
相關文章
相關標籤/搜索