你們好,我給你們分享一下仿豆瓣app的教程。固然了,咱們不是用原生去實現,而是用前端框架vuejs來實現豆瓣app。————第一次寫文章,寫得很差請見諒。css
爲何咱們選擇豆瓣app 來作這樣一個教程?前端
是由於我很早就接觸豆瓣這個網站,我比較喜歡看豆瓣裏面電影和文章的點評。而且豆瓣提供了很是豐富的一個api接口供咱們使用。也就是說咱們能夠不經過後端,直接經過前端ajax來獲取電影和圖書的數據,來組裝咱們app。vue
咱們能夠看一下豆瓣app首頁是一個什麼樣子 gifwebpack
以上就是豆瓣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
將所須要用的資源,拷貝到項目中,這裏我經過解壓豆瓣app得到他的一些圖片素材,拷入到src/assets/images目錄裏。
css這裏我用到了normaliz.css
在src下,新建了一個pages目錄,存放每個頁面組件,能夠看一下咱們的目錄
因爲咱們的首頁更改了位置,因此在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
這是咱們將要實現的效果圖。
咱們先來分析一下這個組件的結構。
這個組件分爲兩部分:第一個是組件的外層容器,第二個是組件的子容器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>
完成的效果。
*
光有一個死的界面,沒有點擊切換的效果怎麼能行?
如下咱們經過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組件就完成了~
感謝餓了麼團隊給咱們帶來了這麼好的ui組件!
源碼下載 連接:http://pan.baidu.com/s/1qYlR8g0 密碼:9yph
下載安裝
npm install npm run dev