vue2饿了么--商家弹出图层的实现

<div v-show="detailShow" class="detail">
</div>
.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
    };
  }

当我们点击按钮的时候,图层出现

<div v-if="seller.supports" class="support-count" @click = "showdetail">
<div 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);
    <div v-show="detailShow" class="detail">
      <div class="detail-wrapper clearfix">
        <div class="detail-main">
      </div>
      <div class="detail-close" @click="hideDetail">
        <span class="icon-close"></span>
      </div> 

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>
<div class="star">  <!-- star表示一行星星,star-item循环这几个星星,starType返回star-48 -->
    <div 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>
    </div>
</div>
</template>

首先,星星接收一个尺寸(24/36/48)和评分(4.2)

        <div class="star-wrapper">
            <star :size="48" :score="seller.score"></star>
          </div>
    props: {
      size: {
        type: Number
      },
      score: {
        type: Number
      }
    }

计算starType属性,图片名称实例:[email protected]

 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组件

         <div class="star-wrapper">
            <star :size="48" :score="seller.score"></star>
          </div>

之后动态生成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布局

          <div class="title">
            <div class="line"></div>
            <div class="text">优惠信息</div>
            <div class="line"></div>
          </div>
          .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按钮

 <div class="detail-close" @click="hideDetail">
        <span class="icon-close"></span>
      </div>
 hideDetail() {
      this.detailShow = false;
    }

添加transition实现动画,完成

为背景添加模糊效果

      z-index: -1
      filter: blur(10px) /* 模糊效果*/

猜你喜欢

转载自blog.csdn.net/qq_22317389/article/details/81103867