仿寫去哪兒app項(xiàng)目和詳細(xì)總結(jié)

我的代碼地址:https://gitee.com/Zl190/Travel
效果圖:

image.png

image.png

image.png

image.png

image.png

image.png

具體的話你們可以下載我的項(xiàng)目參考一下,有一些特效也可以自己改進(jìn)。
接下來我要開始總結(jié)我所做的去哪兒app的一些心得了。

1.移動端開發(fā)中的1px邊框問題,由于在不同屏幕上,可能會使得1px實(shí)際在移動端顯示不是1px,怎么解決?

解決:通過設(shè)置對應(yīng)viewport的rem基準(zhǔn)值,這種方式就可以像以前一樣輕松愉快的寫1px了。

2.移動端click事件延遲300ms的解決方法?

先在終端下載fastclick

cnpm install fastclick --save

然后在main.js里面引入

import fastClick from 'fastclick'

使用fastClick

fastClick.attach(document.body)

3. scoped限制該vue文件下的css僅在該.vue文件下使用。

4. stylus樣式的應(yīng)用:

下載stylus

cnpm install stylus --save
cnpm install stylus-loader --save

使用

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

stylus使用變量的話可以在src下面的assets新建個(gè)文件夾css,然后建個(gè) varibles.styl來存放要使用的一些變量.
最后在<style lang="stylus" scoped/>標(biāo)簽內(nèi)引入

@import '../../../assets/css/varibles.styl'

這樣就可以使用那些變量了。

5.簡化路徑

@在路徑中指的是src目錄,即@/assets/css/reset.css,注意,在css樣式中引入其他css目錄時(shí),需要寫成~@/assets/css/reset.css。

簡化路徑,為常用路徑簡化別名,如src/common可簡化為common/:
步驟:在build下webpack.base.conf.js文件下
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'), //@這是src目錄的別名
'common':resolve('src/common') //這是src/common的別名,從而用common替代src/common路徑達(dá)到簡化效果
}
}

6. iconfont字體圖標(biāo)的應(yīng)用:

6.1 在iconfont注冊賬號,建立一個(gè)項(xiàng)目,然后將需要的圖標(biāo)加入到該項(xiàng)目下,下載到本地電腦該項(xiàng)目文件夾下src->assets->iconfont中。
6.2 在iconfont.css的url中修改字體在本地的路徑,在main.js中直接引入該文件import ".import './assets/css/iconfont.css'"。
6.3 <span class="iconfont"></span>即可顯示該圖標(biāo)字體。

7.解決網(wǎng)速過慢獲取資源頁面抖動問題

設(shè)置元素的寬高比例固定就行了

.swiper
        overflow : hidden
        width :100%
        height :0
        padding-bottom :31.25%//即高始終為寬的31.25%

8.scoped穿透

如果我們給樣式設(shè)置了scoped,這個(gè)時(shí)候組件里面的樣式既不能影響外部樣式,也不能比外部樣式所影響。

 .swiper >>> .swiper-pagination-bullet-active
        background-color :#fff

9.vue-awersome-swipper數(shù)據(jù)加載后直接顯示最后一頁問題。

解決:使用axios獲取數(shù)據(jù)傳遞給輪播組件以后直接顯示了最后一頁,此時(shí)可以使用v-if通過判斷數(shù)組長度返回的是true還是false

<swiper :options="swiperOption" v-if="showimg">
 showimg(){
        return this.swiperList.length
      }

這樣這個(gè)問題就解決了。

10.vue-awesome-swiper輪播插件的應(yīng)用:

    1.在main.js中引入全局插件:
        npm install vue-awesome-swiper@2.6.7 --save
        import VueAwesomeSwiper from 'vue-awesome-swiper'
        import "swiper/dist/css/swiper.css"
        Vue.use(VueAwesomeSwiper)
     2.
   <swiper :options="swiperOption" v-if="showimg">
  <!-- slides -->
  <swiper-slide v-for="list of swiperList" :key="list.id">
      <img class="swiper-img" :src="list.imgUrl"/>
  </swiper-slide>
  <!-- Optional controls -->
  <div class="swiper-pagination" slot="pagination"></div>
</swiper>

swipperDOM結(jié)構(gòu)變化導(dǎo)致的滾動問題
如果我們插入swipper中的DOM有所變化,那么滾動效果就會變得非常的差,這個(gè)時(shí)候我們可以設(shè)置他的swipperOptions里面的observeParents以及observer

 data () {
   return {
     swiperOption: {
       pagination : '.swiper-pagination',
              paginationType : 'fraction',
              observer:true,
              observeParents:true,
     }
   }
 }

11.跨平臺的axios的使用:實(shí)現(xiàn)跨平臺的請求

      10.1  npm install axios --save  //或者<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
      10.2  import axios from "axios"
      10.3  methods:{            //通過.json文件模擬后端接受的數(shù)據(jù),將index.json文件放在static里面
                  getHomeInfo(){
                      axios.get("./static/mock/index.json").then(this.getHomeInfoSucc)
                  },
                  getHomeInfoSucc(res){
                      console.log(res)
                  }
              }

12.在config>index.js里面 做如下設(shè)置,則可以實(shí)現(xiàn)通過調(diào)用api/index.json接口時(shí),自動轉(zhuǎn)到本地static/mock/index.json文件

             proxyTable: {
                "/api":{
                    target:"http://location:8098",
                    pathRewrite:{
                        "^/api":"/static/mock"
                    }
                }
            }

13. Bscroll使用方法:

    1. npm下載better-scroll:npm install better-scroll --save;
    2. 引入better-scroll:import Bscroll from "better-scroll";
    3. 定義標(biāo)簽dom:  < div ref="wrapper"></div>
    4. 實(shí)例化bscroll:  this.scroll = new BScroll(this.$refs.wrapper, {click: true});

注意:Bscroll提供滾動到指定DOM位置的API,this.scroll.scrollToElement(dom);

全局事件
如果把事件綁定到window上面比如scroll事件,那么在推出這個(gè)頁面的時(shí)候一定要進(jìn)行解綁,不然在其他的頁面也會受到這個(gè)事件的影響,造成bug

  mounted () {
    window.addEventListener('scroll', this.handleScroll)
  },
  beforeDestroy () {
    window.removeEventListener('scroll', this.handleScroll)
  }

14.滾動行為

如果我們的某個(gè)頁面是滾動的,切設(shè)置了keep-alive,那么我們進(jìn)入其他頁面返回的時(shí)候如果讀取了緩存,那么這個(gè)緩存是包括滾動行為的,則原來頁面滾動到什么位置現(xiàn)在也滾動到什么位置如果我們不希望出現(xiàn)這種情況,可以在路由中設(shè)置滾動行為

scrollBehavior (to, from, savedPosition) {   return { x: 0, y: 0 } }

15、組件name的作用

1、在遞歸組件中實(shí)用,即,我們在創(chuàng)建組件的時(shí)候就可以使用組件自身

2、keep-alive的exclude中實(shí)用,用來避免某些組件進(jìn)入緩存

3、vue-devtools中的使用

16.keep-alive

使用keep-alive可以進(jìn)行緩存,這樣就不會每次進(jìn)入相同的頁面都會進(jìn)行數(shù)據(jù)請求了,能提高用戶體驗(yàn)、在使用keep-alive以后會多兩個(gè)生命周期函數(shù):activated以及deactivated,我們可以在這里進(jìn)行一些判斷操作,來決定是否需要緩存,是否需要執(zhí)行數(shù)據(jù)獲取。此外,如果我們是給整個(gè)路由router-view組件進(jìn)行了keep-alive,并且在這里執(zhí)行了一些exinclude設(shè)置

<keep-alive exclude="Detail">
<router-view/>
</keep-alive>
<keep-alive exclude="組件name名"> //exclude="組件name名"表示該組件不需要緩存,即每次跳轉(zhuǎn)到頁面都重新加載mounted生命周期

   activated(){ //因?yàn)閗eep-alive而多出來的生命周期,即頁面初始加載時(shí)和mounted一樣執(zhí)行,且在每次頁面跳轉(zhuǎn)返回當(dāng)前頁面時(shí),仍然會執(zhí)行,但是mounted因?yàn)樵趉eep-alive下不會執(zhí)行了
      if(this.lastCity !== this.city){   //即跳轉(zhuǎn)回當(dāng)前頁面時(shí),如果選擇的城市發(fā)生改變,則再次發(fā)生ajax,否則就不發(fā)生ajax
          this.lastCity=this.city;   
          this.getHomeInfo();   
      }
  }

那么對應(yīng)的里面就沒有這兩個(gè)生命周期函數(shù)了,我們不能使用這兩個(gè)函數(shù)

17

          <router-link
                     class="item-list border-bottom" 
                     v-for="item of recommendList" 
                     :key="item.id"
                     tag="li"
                     :to="'/details/'+item.id"></router-link>

這種寫法,避免了a標(biāo)簽改變了li表示內(nèi)里的文字顏色,相當(dāng)于<li></li>且自帶跳轉(zhuǎn)頁面的功能。
<router-link tag="div" :to="."></router-link> 其中to="."表示返回上一頁

18.路由帶參數(shù)傳值:

{
  path: '/detail/:id',//動態(tài)id
  component: Detail
}

19.vue中的遞歸組件:即組件里面調(diào)用組件自己本身;

通過name:" detailComponent"名,去調(diào)用<detail-component :list="參數(shù)"></detail-component>


image.png

20.localStorage本地存儲:

let defaultCity = '上饒'
try {
// 如果存在本地的城市,則讓默認(rèn)的城市等于本地選擇的城市
  if (localStorage.city) {
    defaultCity = localStorage.city
  }
} catch (e) {

}
export default {
  city: defaultCity
}

21.

vuex的使用:如果您不打算開發(fā)大型單頁應(yīng)用,使用 Vuex 可能是繁瑣冗余的。確實(shí)是如此——如果您的應(yīng)用夠簡單,
您最好不要使用 Vuex。一個(gè)簡單的 global event bus 就足夠您所需了。但是,如果您需要構(gòu)建一個(gè)中大型單頁應(yīng)用,您很可能會考慮如何更好地在組件外部管理狀態(tài),
Vuex 將會成為自然而然的選擇;

步驟:21.1 安裝vuex:npm install vuex --save ;
21.2 src文件夾下創(chuàng)建一個(gè)store文件夾用于處理vuex;
21.3 在store文件夾下創(chuàng)建index.js;
21.4 在index.js里寫:

        import Vue from "vue"
        import Vuex from "vuex"
        Vue.use(Vuex);   //vue里面使用插件(如vuex)都是通過Vue.use(插件名)
        export default new Vuex.Store({  //創(chuàng)建new Vuex.Store倉庫,并導(dǎo)出export
            state:{   //存放全局公用的數(shù)據(jù)
                city:"上饒",     //首頁頭部顯示的城市,默認(rèn)為重慶
            },
            actions:{   //接受模塊通過this.$store.dispatch傳遞過來的changeCity=item的數(shù)據(jù),ctx.commit表示把該數(shù)據(jù)名和值傳遞給mutations
               changeCity (txt, value) {

// 通過txt的commit方法觸發(fā)mutations里的changeCity,并且傳遞city。

          txt.commit('changeCity', value)
              }
        }

            //注釋:如果是this.$store.commit傳遞過的數(shù)據(jù),可以直接不需要actions,從而直接通過mutations處理修改state的值
            mutations:{   //接受actions通過ctx.commit傳遞的數(shù)據(jù)并處理,即修改state里面的city讓其等于item
                changeCity(state,item){
                    state.city=item;
                }
            }
        })

22.動畫的添加

npm install animate.css --save

下面是我寫的動畫

image.png

然后使用該動畫


image.png

23. vue項(xiàng)目的接口聯(lián)調(diào):即將模擬的json數(shù)據(jù)改成從服務(wù)器獲取數(shù)據(jù):

在config->index.js下:

        dev: {
            assetsSubDirectory: 'static',
            assetsPublicPath: '/',
            proxyTable: {
                "/api":{
                    target:"http://localhost:80", // 將此改為服務(wù)地址,即發(fā)送/api的ajax會從該地址獲取數(shù)據(jù)
                }
            },

24.vue項(xiàng)目打包上線:進(jìn)入該項(xiàng)目的命令行,輸入npm run build,會生成dist文件,然后將該文件里內(nèi)容放在服務(wù)上,如放在xampp->htdocs根目錄文件夾下

補(bǔ)充一下:
還有函數(shù)節(jié)流
在我們使用一些滾動事件的時(shí)候,我們可以設(shè)置節(jié)流來提高效率,比如滾動事件如果在一定時(shí)間內(nèi)連續(xù)滾動則不進(jìn)行處理,直到最后確定滾動出來了,這樣能提高性能。常見解決方式是設(shè)置一個(gè)定時(shí)器來進(jìn)行解決

//   設(shè)置個(gè)定時(shí)器性能更好
      this.timer = setTimeout(() => {
        var result = [];
        // 遍歷citier這個(gè)數(shù)組對象   i :0,1,2,3,...
        for (var i in this.cities) {
          // 循環(huán)這個(gè)數(shù)組上的所有元素
          this.cities[i].forEach(value => {
            // 如果當(dāng)前對象的spell和name包含keywords關(guān)鍵字則向新創(chuàng)建的result數(shù)組中添加該對象
            if (
              value.spell.indexOf(this.keywords) > -1 ||
              value.name.indexOf(this.keywords) > -1
            ) {
              result.push(value);
            }
          });
        }
        this.list = result;
      }, 100);

這是我寫完去哪兒app的心得。
想學(xué)習(xí)前端的同學(xué),我留下[傳送門](https://www.liaoxuefeng.com

),碼子不易,如果文章對你有幫忙,點(diǎn)個(gè)贊唄

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容