闲暇之余对照了小米商城官网首页的展示效果,自己仿写了首页的头部页面,渲染图为下:
不知道小米商城用的是什么框架,我这里使用的是vue + element,由于是单页面,且没有添加图片以及调用接口,所以页面时静态的。
其中有部分细节需要注意:
1、下载APP这里,有一个动态的效果,鼠标放上去会出现一张二维码,位置正好是在下载APP下面,且是由上往下滑出,小米这种大厂的效果还是很丝滑的,我参考了别人的思路,可以同过css的属性以及结合js来实现:
css属性为:height:0; overFlow:hidden;transition: height .3s linear;
js:绑定鼠标进入事件和鼠标离开事件,当鼠标进入时,获取二维码所在的dom,给它动态设置一个height高度,当鼠标离开时,同样的给它将height置为0,这样就可以丝滑的滑动了;
二维码恰好在下载APP下面,用到的css定位这个属性
2、购物车这里的思路同下载APP一样
3、有图片的这一块内容,其实也是向下滑动而出,所以css思路是一样的
尽量保持了和小米完全一样的渲染效果,话不多说,直接上代码
<template>
<div>
<div>
<div class="header">
<div class="sit-topbar container">
<ul class="nav-left">
<li v-for="item in navLeft" :key="item.prop" class="li-container" @mouseenter="ifShowCode(true,item)" @mouseleave="ifShowCode(false,item)">
<a :href="item.href" target="_blank">{{ item.label }}</a>
<span v-if="item.sep" class="sep">|</span>
<i v-if="item.pictrue" :ref="item.ref + 'Triangle'" class="triangle" />
<div :ref="item.ref" class="dowload" :class="{showPictrue: item.pictrue}">
<a href="https://www.mi.com/appdownload" target="_blank">
<div class="qrCode">这是一张二维码</div>
</a>
</div>
</li>
</ul>
<div class="nav-right">
<ul class="login">
<li v-for="item in navRight" :key="item.prop" class="li-container">
<a :href="item.href" target="_blank">{{ item.label }}</a>
<span v-if="item.sep" class="sep">|</span></li>
</ul>
<div class="shop" @mouseenter="ifShowShopCar(true)" @mouseleave="ifShowShopCar(false)">
<div class="shopCar-button">
<i class="el-icon-shopping-cart-2" />
<span>购物车</span>
<span>({{ count }})</span>
</div>
<div ref="shopCar" class="shopCar-select">
购物车中还没有商品,赶紧选购吧!
</div>
</div>
</div>
</div>
</div>
<div class="sit-header">
<div class="sit-header-style container">
<div class="log">MI</div>
<ul class="sit-header-ul">
<li v-for="item in headerList" :key="item.prop" @mouseenter="ifShowRecommend(true,item)" @mouseleave="ifShowRecommend(false,item)">
<a v-if="item.href" :href="item.href" target="_blank">{{ item.label }}</a>
<span v-else>{{ item.label }}</span>
</li>
</ul>
<div class="seach-container">
<el-select
v-model="value"
filterable
remote
reserve-keyword
clearable
placeholder="请输入关键词"
:remote-method="remoteMethod"
:loading="loading"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<div class="seach-button">
<i class="el-icon-search" />
</div>
</div>
</div>
<!-- recommend 隐藏框 -->
<div ref="recommend" class="sit-header-recommend" @mouseenter="ifShowRecommend(true)" @mouseleave="ifShowRecommend(false)">
<ul class="recommend-container container">
<li v-for="item in recommendList" :key="item.label" class="recommend-item">
<div class="picture-container">
<div class="recommend-picture">一张图片</div>
</div>
<span class="recommend-label" style="color:#333;font-size:12px">{{ item.label }}</span>
<span class="recommend-label" style="color:#FF6A00;font-size:12px">{{ item.price }} 起</span>
</li>
</ul>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
count: 0,
navLeft: [
{ label: '小米商城', prop: 'miShoppingMall', href: 'https://www.mi.com/index.html', sep: true },
{ label: 'MIUI', prop: 'miui', href: 'https://home.miui.com', sep: true },
{ label: 'loT', prop: 'lot', href: 'https://iot.mi.com', sep: true },
{ label: '云服务', prop: 'cloudServices', href: 'https://iot.mi.com', sep: true },
{ label: '天星数科', prop: 'shar', href: 'https://iot.mi.com', sep: true },
{ label: '有品', prop: 'fashion', href: 'https://iot.mi.com', sep: true },
{ label: '小爱开放平台', prop: 'xaioai', href: 'https://iot.mi.com', sep: true },
{ label: '企业团购', prop: 'group', href: 'https://iot.mi.com', sep: true },
{ label: '资质证照', prop: 'license', href: 'https://iot.mi.com', sep: true },
{ label: '协议规则', prop: 'rules', href: 'https://iot.mi.com', sep: true },
{ label: '下载APP', prop: 'download', href: 'https://iot.mi.com', sep: true, ref: 'showQR', pictrue: true },
{ label: '智能生活', prop: 'smartLife', href: 'https://iot.mi.com', sep: true },
{ label: 'Select Location', prop: 'selectLocation', href: 'https://iot.mi.com' }
],
navRight: [
{ label: '登录', prop: 'login', href: 'https://www.mi.com/index.html', sep: true },
{ label: '注册', prop: 'register', href: 'https://www.mi.com/index.html', sep: true },
{ label: '消息通知', prop: 'message', href: 'https://www.mi.com/index.html' }
],
headerList: [
{ label: 'Xiaomi手机', prop: 'xiaomi',
list: [
{ label: 'xiaomi 1', price: 1799, href: '' },
{ label: 'xiaomi 2', price: 1799, href: '' },
{ label: 'xiaomi 3', price: 1799, href: '' },
{ label: 'xiaomi 4', price: 1799, href: '' },
{ label: 'xiaomi 5', price: 1799, href: '' },
{ label: 'xiaomi 6', price: 1799, href: '' }
],
showRecommend: true
},
{ label: 'Redmi红米', prop: 'redmi',
list: [
{ label: '红米 1', price: 1299, href: '' },
{ label: '红米 2', price: 1299, href: '' },
{ label: '红米 3', price: 1299, href: '' },
{ label: '红米 4', price: 1299, href: '' },
{ label: '红米 5', price: 1299, href: '' },
{ label: '红米 6', price: 1299, href: '' }
],
showRecommend: true
},
{ label: '电视', prop: 'tv',
list: [
{ label: '电视 1', price: 7999, href: '' },
{ label: '电视 2', price: 7999, href: '' },
{ label: '电视 3', price: 7999, href: '' },
{ label: '电视 4', price: 7999, href: '' },
{ label: '电视 5', price: 7999, href: '' },
{ label: '电视 6', price: 7999, href: '' }
],
showRecommend: true },
{ label: '笔记本', prop: 'computer',
list: [
{ label: '笔记本 1', price: 4999, href: '' },
{ label: '笔记本 2', price: 4999, href: '' },
{ label: '笔记本 3', price: 4999, href: '' },
{ label: '笔记本 4', price: 4999, href: '' },
{ label: '笔记本 5', price: 4999, href: '' },
{ label: '笔记本 6', price: 4999, href: '' }
],
showRecommend: true },
{ label: '平板', prop: 'pad',
list: [
{ label: '平板 1', price: 2399, href: '' },
{ label: '平板 2', price: 2399, href: '' }
],
showRecommend: true },
{ label: '家电', prop: 'homeAppliances',
list: [
{ label: '家电 1', price: 3699, href: '' },
{ label: '家电 2', price: 3699, href: '' },
{ label: '家电 3', price: 3699, href: '' },
{ label: '家电 4', price: 3699, href: '' },
{ label: '家电 5', price: 3699, href: '' },
{ label: '家电 6', price: 3699, href: '' }
],
showRecommend: true },
{ label: '路由器', prop: 'router',
list: [
{ label: '路由器 1', price: 199, href: '' },
{ label: '路由器 2', price: 199, href: '' },
{ label: '路由器 3', price: 199, href: '' },
{ label: '路由器 4', price: 199, href: '' },
{ label: '路由器 5', price: 199, href: '' },
{ label: '路由器 6', price: 199, href: '' }
],
showRecommend: true },
{ label: '服务', prop: 'service', href: 'https://www.mi.com/index.html' },
{ label: '社区', prop: 'community', href: 'https://www.mi.com/index.html' }
],
value: '',
loading: false,
exampleList: [
{ label: '全部商品', value: 'all' },
{ label: '小米平板5 pro', value: 'padFivePro' },
{ label: '手机', value: 'phone' },
{ label: '黑鲨4s', value: 'shark' },
{ label: '耳机', value: 'headset' },
{ label: '笔记本', value: 'notebook' },
{ label: '洗衣液', value: 'laundry' }
],
options: [],
recommendList: []
}
},
mounted() {
this.options = this.exampleList
},
methods: {
ifShowCode(ifShow, val) {
if (val.pictrue) {
this.$refs[val.ref][0].style.height = ifShow ? '160px' : 0
this.$refs[val.ref + 'Triangle'][0].style.display = ifShow ? 'block' : 'none'
}
},
ifShowShopCar(ifShow) {
this.$refs.shopCar.style.height = ifShow ? '100px' : 0
},
ifShowRecommend(ifShow, val) {
// 这里的边框需要js控制,单纯的css没有效果,没有找到原因
this.$refs.recommend.style.borderTop = ifShow ? '1px solid #DCDFE6' : 'none'
if (!val) {
this.$refs.recommend.style.height = ifShow ? '250px' : 0
return
}
if (val.showRecommend) {
this.recommendList = val.list
this.$refs.recommend.style.height = ifShow ? '250px' : 0
}
},
remoteMethod(query) {
if (query !== '') {
this.loading = true
setTimeout(() => {
this.options = []
this.loading = false
}, 200)
} else {
this.options = this.exampleList
}
}
}
}
</script>
<style lang='scss' scoped>
.header{
background-color: #333333;
}
.container{
width: 1226px;
margin: 0 auto;
}
.sit-topbar{
height: 40px;
line-height: 40px;
display: flex;
justify-content: space-between;
a{
font-size: 12px;
color: #b0b0b0;
}
ul{
display: flex;
.li-container{
position: relative;
.sep{
margin: 0 .3em;
color: #424242;
}
&:hover{
a{
cursor: pointer;
color: #fff;
}
}
}
}
.nav-right{
display: flex;
align-items: center;
.shop{
width: 120px;
text-align: center;
margin-left: 15px;
background: #424242;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
color: #b0b0b0;
position: relative;
&:hover{
background: #fff;
cursor: pointer;
color: #FF6A00;
}
.shopCar-select{
background: #fff;
color: #b0b0b0;
position: absolute;
z-index: 20;
top: 40px;
right: 0;
width: 316px;
height: 0;
line-height: 100px;
box-shadow: 0 5px 5px #aaa;
overflow: hidden;
transition: height .3s linear;
}
i{
font-size: 20px;
}
}
}
}
.dowload{
display: none;
.qrCode{
color: #666;
}
}
.showPictrue{
display: block;
background: #fff;
font-size: 12px;
text-align: center;
width: 120px;
height: 0;
line-height: 150px;
position: absolute;
left: -30px;
z-index: 20;
box-shadow: 0 1px 5px #aaa;
overflow: hidden;
transition: height .3s linear;
}
.triangle{
display: none;
width: 0;
height: 0;
border-bottom: 10px solid #fff;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
position: absolute;
top: 30px;
left: 15px;
}
.sit-header{
background-color: #fff;
height: 100px;
display: flex;
align-items: center;
position: relative;
.sit-header-style{
display: flex;
justify-content: space-between;
height: 100%;
align-items: center;
.log{
width: 56px;
height: 56px;
color: #fff;
background-color: #FF6A00;
border-radius: 22px;
display: flex;
justify-content: center;
align-items: center;
font-size: 22px;
}
.sit-header-ul{
display: flex;
align-items: center;
height: 100%;
padding: 12px 0 0 30px;
a{
color: #000000;
&:hover{
color: #FF6A00;
}
}
li{
padding: 0 10px;
height: 88px;
line-height: 88px;
&:hover{
cursor: pointer;
color: #FF6A00;
}
}
}
.seach-container{
display: flex;
align-items: center;
.seach-button{
width: 52px;
height: 50px;
border: 1px solid #DCDFE6;
border-left: none;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
&:hover{
cursor: pointer;
border-color: #C0C0CC;
background: #FF6A00;
.el-icon-search{
color: #fff;
}
}
.el-icon-search{
font-weight: bold;
}
}
}
}
}
.el-select{
width: 245px;
}
/deep/.el-input__inner{
height: 50px;
border-radius: 0;
&:hover{
.seach-button{
border-color: #C0C0CC;
}
}
}
.sit-header-recommend{
display: none;
background: #fff;
width: 100%;
position: absolute;
z-index: 10;
top: 100px;
height: 0;
line-height: 250px;
display: flex;
align-items: center;
overflow: hidden;
transition: height .3s linear;
box-shadow: 0px 20px 20px -20px #aaa; // 只有下边框有阴影效果
.recommend-container{
display: flex;
.recommend-item{
width: calc(100% / 6);
display: flex;
flex-direction: column;
align-items: center;
&:not(:last-child){
.picture-container{
padding-right: 50px;
border-right: 1px solid #DCDFE6;
}
.recommend-label{
padding-right: 50px;
}
}
.recommend-picture{
background: pink;
width: 120px;
height: 130px;
line-height: 130px;
text-align: center;
}
.recommend-label{
height: 20px;
line-height: 20px;
}
}
}
}
</style>
可以看到,代码中的数据用的都是模拟数据,目的是让页面看来丰满一些,其中css战略所有的代码一半左右,目的是为了处理细节,使页面看起来同小米商城尽量一样
当然,里面还有很多可以优化的地方,请看到的朋友讨论指正