vue模擬攜程官網的搭建

仿造攜程官網

題外話:

剛開始學前端的時候,有一天看到攜程官網.就但願有一天能模擬搭出來.
本身拖拖拉拉的一直沒整, 可是可是麻麻我終於完成了!!
(曾經親愛的同事把傳送門刪掉了不感謝他了 fk)
感謝葉師兄拯救了我攜程攜程 源碼仿攜程源碼
仿攜程gif圖javascript

目錄結構

  • 基於vue+less進行開發,配合強行在攜程複製的數據搭建的網站
  • 目錄是基於vue-cli的基礎下搭建的.

圖片描述

  • build/config配置文件
  • src是主要內容(assets包括公用的js文件,css樣式/components是公用組件/module是頁面)
  • dist是打包後的文件夾 node_modules是依賴包 其餘就是默認的配置文件

思路

小小講一下本身拿到攜程官網的時候是怎麼拆開的(若是寫的不對請麻煩各位指出指導)

1.首先是靜態頁面

剛剛學前端的時候 看到攜程網就亂拳敲打.一點點html css強寫,
後面工做的緣由用了vue,就推倒舊的從新寫了.css

  • 頁面結構是分爲這幾塊:(如圖)html

    1. 包括logo的header
    2. 導航欄
    3. icon快捷入口
    4. 廣告swipe和搜索框
    5. 各專題區
    6. 底部快捷入口
    7. 底部
    8. 電梯
    9. fixed的交互框

頁面結構

  • 有頁面結構以後.就是基本功了.而後一點點搭頁面, (優化把公用組件抽出來.)

2.而後是頁面數據

哎,沒想到好的辦法.就搭頁面的時候,順便在攜程網上面一點點的copy下來.
(我看隔壁的仿頁面貼都是經過接口的.小弟仍是菜了點)
mock_data
而後經過每一個須要數據的頁面去引入這個mock.js...前端


3.樣式

普通的頁面樣式就不說啦.你們慢慢搭就好.
share一些less的mixin方法.vue

// display vertical集合
#display_type{
    .dsp-middle{
        display: inline-block;
        vertical-align: middle;
    }
    .dsp-top{
        display: inline-block;
        vertical-align: top;
    }
}

// 三角形(向下)
.arrow_down(@size, @color: black){
    //@size大小 @color顏色
    margin-left: 5px;
    &:after{
        content: '';
        display: inline-block;
        border-top: @size solid @color;
        border-left: @size solid transparent;
        border-right: @size solid transparent;
        border-bottom: @size solid transparent;
    }
}

用的比較多的2個mixin就是上面這2個.一個是display的作佈局使用, 一個是人工三角形orz.
若是想要用mixin的時候,須要在css中用@import的方法引入才能用.(用js的方式,破了很久破不了放棄)java

  • 引入以後直接在頁面裏面使用便可
  • #display_type > .dsp-middle 或另一個;
  • .arrow_down(3px, #fff);

4.響應式佈局

由於個人樣式是經過less寫的.
那就看着攜程官網.一點點測試.一點點完善咯.沒啥好辦法.
部分代碼以下.node

@media screen and (max-width: 1200px){
            margin-right: 20px;
            
            &:last-child{
                display: none;
            }
        }

5.電梯

這個電梯是存在於專題區裏面的,因此我給每一個專題的div添加了一個不用的類名,用來獲取當前div的滾動高度.
而後在鉤子函數mounted()裏面,去獲取各個專題的高度git

const s = document.getElementsByClassName('scroll-hook');
        
    for(let dom of s){
        let scoll_h = dom.offsetTop + dom.offsetParent.offsetTop;
        this.scroll_data.push(scoll_h);
    }

電梯的精髓就是在:github

  1. 根據當前的滾動高度,而後動態改變active的標識;
  2. 點擊對應的標識,頁面會滾到對應的區域;
  3. 頁面滾動的時候,在某個固定的位置待着

那麼就對應的寫bie.vue-cli

1.電梯的html渲染(ps. lift.index是每個電梯的類名, lift_flag是區域的標識),而後在mounted()裏給window註冊一個scroll的監聽事件,而後去獲取當前的滾動高度,而後進行判斷

<ul class="lift-wrapper" :style="`top:${lift_top}px;`">
    <li 
        class="lift-item" 
        :class="[lift.index,  {'lift-active': (lift_index === lift_flag)}]"
        v-for="(lift,lift_index) in d"
        @click="lift_click(lift_index)">
        <span class="skip">{{lift.name}}</span>
    </li>
</ul>

2.點擊滾動,寫了一個原生的笨方法,(document.dEl那有一個兼容問題)

//頁面滾動方法
function page_scroll_to(cur, tar){
    /*
        params:
        cur 當前高度
        tar 目標高度
    */
    var during = 10; //持續時間(ms)
    var times = 20;  //持續次數
    var i = 1;       //持續標識
    var s_flag;

    if(cur < tar){
        var s = (tar - cur) / times; //滾動距離
        s_flag = setInterval(() => {
            //解決兼容性問題(本來使用documentElement便可)
            document.documentElement.scrollTop = cur + s * i;
            document.body.scrollTop = cur + s * i;
            i++;

            if(i>times){
                clearInterval(s_flag);
            }
        }, during)
    }
    else{
        var s = (cur - tar) / times;
        s_flag = setInterval(() => {
            //解決兼容性問題
            document.documentElement.scrollTop = cur - s * i;
            document.body.scrollTop = cur - s * i;
            i++;

            if(i>times){
                clearInterval(s_flag);
            }
        }, during)
    }
}

3.樣式我是直接copy攜程的. 滑動高度呢就根據滾動高度去計算, 而後用js給電梯的div寫一個內聯樣式,動態的去改變


6.throttle事件

由於給window註冊了一個scroll事件,當你一滾動,會瘋狂觸發scroll,可能在線上的會致使瀏覽器有壓力(猜的)
因此本身寫了一個throttle方法去優化這一塊,
而後在vue的原型對象中註冊了一下,能夠在後續直接this.throttle只用

function throttle(fn, delay, context) {
    /*
        throttle函數(每delay時間,觸發一次fn函數)

        param:
        fn           執行函數
        delay        持續時間(ms)
        context      做用域
    */

    var last;
    //定時器
    var timer;

    return function(){
        //獲取當前的毫秒數
        var now = +new Date();

        //判斷時間
        if(last && now < last + delay){
            clearTimeout(timer);

            timer = setTimeout(function() {
                last = now;
                fn.apply(context);
            }, delay)
        }
        else{
            last = now;
            fn.apply(context);
        }
    }
}
Vue.prototype.throttle = throttle;

7.lazyload

頁面大了一進入就觸發所有的請求,確定不那麼棒,因此此處引入了lazyload.
攜程的lazyload除了圖片.還有每一個專題區(忽略愛心 - -).
攜程lazy-load
ps.最開始引用了vue-lazyload這個模塊,而後裏面有一個lazyComponent配置項,能夠用來設置一整塊的,可是這個有一個不足的地方,就是當你頁面在比較下面的時候去刷新, lazyComponent只會update當前可視區域的部分,可視區域上面的區域就無論你........
pss.因此我本身經過上面的電梯,本身寫了一個,而後將flag標識經過組件之間傳入,而後組件內部經過watch去監控.而後動態從初始化狀態更新爲內容區.


結尾

其實就是一個普通的頁面搭建,你們若是有空其實一點點就能搭出來的,
不知道強行分享的東西有沒有更好的方法呢,若是有麻煩各位指導一下小弟.
以上完畢,感謝你們感謝你們.(若是侵權了,立刻下架,僅供交流學習)

最後最後,攜程在手,說走就走.
相關文章
相關標籤/搜索