欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

vue2饿了么下商家弹出图层的实现教程(代码)

程序员文章站 2022-06-05 15:25:52
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) /* 模糊效果*/