vue模拟携程官网的搭建

仿造携程官网

题外话:

刚开始学前端的时候,有一天看到携程官网.就希望有一天能模拟搭出来.
自己拖拖拉拉的一直没整, 但是但是麻麻我终于完成了!!
(曾经亲爱的同事把传送门删掉了不感谢他了 fk)
感谢叶师兄拯救了我携程携程 源码仿携程源码
仿携程gif图

目录结构

  • 基于vue+less进行开发,配合强行在携程复制的数据搭建的网站
  • 目录是基于vue-cli的基础下搭建的.

图片描述

  • build/config配置文件
  • src是主要内容(assets包括公用的js文件,css样式/components是公用组件/module是页面)
  • dist是打包后的文件夹 node_modules是依赖包 其他就是默认的配置文件

思路

小小讲一下自己拿到携程官网的时候是怎么拆开的(如果写的不对请麻烦各位指出指导)

1.首先是静态页面

刚刚学前端的时候 看到携程网就乱拳敲打.一点点html css强写,
后面工作的原因用了vue,就推倒旧的重新写了.

  • 页面结构是分为这几块:(如图)

    1. 包括logo的header
    2. 导航栏
    3. icon快捷入口
    4. 广告swipe和搜索框
    5. 各专题区
    6. 底部快捷入口
    7. 底部
    8. 电梯
    9. fixed的交互框

页面结构

  • 有页面结构之后.就是基本功了.然后一点点搭页面, (优化把公用组件抽出来.)

2.然后是页面数据

哎,没想到好的办法.就搭页面的时候,顺便在携程网上面一点点的copy下来.
(我看隔壁的仿页面贴都是通过接口的.小弟还是菜了点)
mock_data
然后通过每个需要数据的页面去引入这个mock.js...


3.样式

普通的页面样式就不说啦.大家慢慢搭就好.
share一些less的mixin方法.

// 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的方式,破了好久破不了放弃)

  • 引入之后直接在页面里面使用即可
  • #display_type > .dsp-middle 或另外一个;
  • .arrow_down(3px, #fff);

4.响应式布局

因为我的样式是通过less写的.
那就看着携程官网.一点点测试.一点点完善咯.没啥好办法.
部分代码如下.

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

5.电梯

这个电梯是存在于专题区里面的,所以我给每个专题的div添加了一个不用的类名,用来获取当前div的滚动高度.
然后在钩子函数mounted()里面,去获取各个专题的高度

    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);
    }

电梯的精髓就是在:

  1. 根据当前的滚动高度,然后动态改变active的标识;
  2. 点击对应的标识,页面会滚到对应的区域;
  3. 页面滚动的时候,在某个固定的位置待着

那么就对应的写bie.

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去监控.然后动态从初始化状态更新为内容区.


结尾

其实就是一个普通的页面搭建,大家如果有空其实一点点就能搭出来的,
不知道强行分享的东西有没有更好的方法呢,如果有麻烦各位指导一下小弟.
以上完毕,感谢大家感谢大家.(如果侵权了,马上下架,仅供交流学习)

最后最后,携程在手,说走就走.
posted @ 2020-01-17 18:10  10年码农  阅读(823)  评论(0编辑  收藏  举报