仿造携程官网
题外话:刚开始学前端的时候,有一天看到携程官网.就希望有一天能模拟搭出来.
自己拖拖拉拉的一直没整, 但是但是麻麻我终于完成了!!
(曾经亲爱的同事把传送门删掉了不感谢他了 fk)
感谢叶师兄拯救了我携程携程 源码仿携程源码
目录结构
- 基于vue+less进行开发,配合强行在携程复制的数据搭建的网站
- 目录是基于vue-cli的基础下搭建的.
- build/config配置文件
- src是主要内容(assets包括公用的js文件,css样式/components是公用组件/module是页面)
- dist是打包后的文件夹 node_modules是依赖包 其他就是默认的配置文件
思路
小小讲一下自己拿到携程官网的时候是怎么拆开的(如果写的不对请麻烦各位指出指导)
1.首先是静态页面
刚刚学前端的时候 看到携程网就乱拳敲打.一点点html css强写,
后面工作的原因用了vue,就推倒旧的重新写了.
-
页面结构是分为这几块:(如图)
- 包括logo的header
- 导航栏
- icon快捷入口
- 广告swipe和搜索框
- 各专题区
- 底部快捷入口
- 底部
- 电梯
- fixed的交互框
- 有页面结构之后.就是基本功了.然后一点点搭页面, (优化把公用组件抽出来.)
2.然后是页面数据
哎,没想到好的办法.就搭页面的时候,顺便在携程网上面一点点的copy下来.
(我看隔壁的仿页面贴都是通过接口的.小弟还是菜了点)
然后通过每个需要数据的页面去引入这个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);
}
电梯的精髓就是在:
- 根据当前的滚动高度,然后动态改变active的标识;
- 点击对应的标识,页面会滚到对应的区域;
- 页面滚动的时候,在某个固定的位置待着
那么就对应的写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除了图片.还有每个专题区(忽略爱心 - -).
ps.最开始引用了vue-lazyload这个模块,然后里面有一个lazyComponent配置项,可以用来设置一整块的,但是这个有一个不足的地方,就是当你页面在比较下面的时候去刷新, lazyComponent只会update当前可视区域的部分,可视区域上面的区域就不管你........
pss.所以我自己通过上面的电梯,自己写了一个,然后将flag标识通过组件之间传入,然后组件内部通过watch去监控.然后动态从初始化状态更新为内容区.
结尾
其实就是一个普通的页面搭建,大家如果有空其实一点点就能搭出来的,
不知道强行分享的东西有没有更好的方法呢,如果有麻烦各位指导一下小弟.
以上完毕,感谢大家感谢大家.(如果侵权了,马上下架,仅供交流学习)
最后最后,携程在手,说走就走.