vue2饿了么下商家弹出图层的实现教程(代码)
...
vue2饿了么下商家弹出图层的实现教程(代码)
<p v-show="detailshow" class="detail">
</p>
.detail
position: fixed
top: 0
left: 0
z-index: 100
width: 100%
height: 100%
overflow: aotu
background-color : rgba(7,17,27,.5);
弹出图层,固定在上方,并通过v-show来控制弹出的隐藏,vue在实例化的时候会去遍历data里的对象,并去给对象添加get所getter和setter。在data中添加detailshow并初始化,默认不展示图层
data() {
return {
detailshow: false
};
}
当我们点击按钮的时候,图层出现
<p v-if="seller.supports" class="support-count" @click = "showdetail">
<p class="bulletin-wrapper" @click = "showdetail" transition="fade">
在methods中定义showdetail方法
showdetail() {
this.detailshow = true;// 点击按钮detailshow显示为true,即显示隐藏的界面
},
接下来实现弹出图层的布局:sticky footer布局,当页面不够长的时候,要有一个区域(关闭按钮)定在视窗的底部,如果内容不够长的话,会被固定在页面的底部
首先,整体页面的固定
.detail
position: fixed
top: 0
left: 0
z-index: 100
width: 100%
height: 100%
overflow: aotu
background-color : rgba(7,17,27,.5);
<p v-show="detailshow" class="detail">
<p class="detail-wrapper clearfix">
<p class="detail-main">
</p>
<p class="detail-close" @click="hidedetail">
<span class="icon-close"></span>
</p>
clearfix清除浮动是一个通用的样式,写在base.styl中,
.clearfix
display inline-block
&:after
display block
content "."
height 0
line-height 0
clear both
visibility hidden
设置内容区和close区
.detail-wrapper /* 外层容器*/
width : 100%
min-height : 100%
.detail-main /* 除close按钮意外的内容区*/
margin-top : 64px
/* detail-wrapper和detail-close平级构成detail内容页,但是detail-wrapper
中的detail-main要在底部留出64px的空间来盛放close符号
即内容没有满屏的话要将close上移
*/
padding-bottom: 64px
.detail-close
position relative
width : 32px
height 32px
margin -64px auto 0 auto /* 对应padding-bottom*/
font-size : 14px
clear both
在detail-main下边添加name和star
.name
line-height 16px
font-size 16px
text-align center
此时,name的宽度是被内容撑开的,无法居中,所以在.detail-wrapper中定义宽度为100%
接下来为星星添加star,星星除了2x和3x图之外,还分为全星(on),半星(half),和没有状态(off)
<template>
<p class="star"> <!-- star表示一行星星,star-item循环这几个星星,startype返回star-48 -->
<p class="star-item" :class="startype"> <!-- itemclasses记为result数组的值,itemclass的值为on off half -->
<span v-for="itemclass in itemclasses" :key = itemclass.id :class = "itemclass" class = "star-item"></span>
</p>
</p>
</template>
首先,星星接收一个尺寸(24/36/48)和评分(4.2)
<p class="star-wrapper">
<star :size="48" :score="seller.score"></star>
</p>
props: {
size: {
type: number
},
score: {
type: number
}
}
计算startype属性,图片名称实例:star24_half@2x.png
computed: {
startype() {
return 'star-' + this.size;
}
}
在style中定义star的样式,与star-48(startype对应)
.star /* 通用样式*/
font-size 0px
.star-item /* 单个星星的样式*/
display inline-block
background-repeat no-repeat
&.star-48
.star-item
&.star-36
.star-item
&.star-24
.star-item
48的实例
&.star-48
.star-item
width 20px
height 20px
margin-right 22px
background-size 20px 20px
&:last-child
margin-right 0
&.on /* 三种状态*/
bg-image('star48_on')
&.half
bg-image('star48_half')
&.off
bg-image('star48_off')
在计算属性中添加itemclasses函数
const length = 5;
const cls_on = 'on'; /* 对应&.on的css样式*/
const cls_half = 'half';
const cls_off = 'off';
itemclasses() {
let result = [];
// 向下去0.5的倍数
let score = math.floor(this.score * 2) / 2;
let hasdecimal = score % 1 !== 0;
let integer = math.floor(score);
for (let i = 0; i < integer; i++) {
result.push(cls_on); // 全星
}
if (hasdecimal) {
result.push(cls_half); // 半星
}
while (result.length < length) { // 灰色星星补齐
result.push(cls_off);
}
return result;
}
}
通过v-for循环就能取到动态的itemclass了
v-for="itemclass in itemclasses" :key = itemclass.id :class = "itemclass"
回到header中引用并注册star组件
<p class="star-wrapper">
<star :size="48" :score="seller.score"></star>
</p>
之后动态生成class属性
<span class = "star-item on"></span>
<span class = "star-item on"></span>
<span class = "star-item on"></span>
<span class = "star-item on"></span>
<span class = "star-item off"></span>
为了方便给star组件定义位置,我们用star-wrapper将star组件包裹起来
.star-wrapper
margin-top 18px
padding 2px 0
text-align center
在往下,文字居中,文字旁边的lian两条线进行自适应,经典的flex布局
<p class="title">
<p class="line"></p>
<p class="text">优惠信息</p>
<p class="line"></p>
</p>
.title
width 80%
margin 28px auto 0 auto
display flex
.line
flex 1 /* 等分*/
position relative
top -6px
border-bottom 1px solid rgba(255,255,255,0.2)
.text
padding 0px 12px
font-size 16px
font-weight 700px
接下来v-for搞定优惠列表
<ul v-if="seller.supports" class="supports">
<li class="support-item" v-for="(item,index) in seller.supports" :key="(item.id,index.id)">
<span class="icon" :class="classmap[seller.supports[index].type]"></span>
<span class="text">{{seller.supports[index].description}}</span>
</li>
</ul>
created() {
this.classmap = ['decrease', 'discount', 'special', 'invoice', 'guarantee'];
}
css,之前写过的
.supports
width 80%
margin 22px auto
.support-item
padding 0 12px
font-size 0px
margin-bottom 12px
&:last-child
margin-bottom 0px
.icon
display inline-block
width 16px
height 16px
vertical-align top
margin-right 6px
background-size 16px 16px
background-repeat no-repeat
&.decrease
bg-image('decrease_2')
&.discount
bg-image('discount_2')
&.guarantee
bg-image('guarantee_2')
&.invoice
bg-image('invoice_2')
&.special
bg-image('special_2')
.text
line-height 16px
font-size 12px
color #ffffff
商家公告部分省略,最后完成弹出图层的close按钮
<p class="detail-close" @click="hidedetail">
<span class="icon-close"></span>
</p>
hidedetail() {
this.detailshow = false;
}
添加transition实现动画,完成
为背景添加模糊效果
z-index: -1
filter: blur(10px) /* 模糊效果*/
下一篇: linux最大文件句柄数量总结