vue构建仿饿了么外卖APP项目记录--2

文章目录

    • 三、header组件开发
        • 1. seller数据对象的获取
        • 2. 数量【5个】按钮的实现
        • 3. 公告区域的实现
        • 4. header组件整体背景图片的设置
        • 5. 弹出层的显示与隐藏(==v-show==)
        • 6. 弹出层的实现(CSS Sticky Footer)
        • 7. star组件的开发和使用(star的size和score)
        • 8. 过渡效果的实现(transition组件)
        • 9. flex布局实现“----xxxx----”效果
        • 10. 其他布局小问题 (凑个整)

三、header组件开发

1. seller数据对象的获取

组件通信:子组件定义props对象接收父组件中传递的数据,然后在header组件中使用seller中的全部数据。注意需要使用v-bind:src
App.vue

header.vue----script

export default {
		props: {
		    seller: {
		      type: Object
		    }
		  }
	}

2. 数量【5个】按钮的实现

  • div结构

     |-div.support-count
     	|-span.count
     	|-i.icon-keyboard_arrow_right
    
  • 相对父元素header绝对定位于右下角的某个区域

  • 箭头使用字体图标实现

    
    
  • css布局

	.support-count
        position: absolute
        right 12px
        bottom 38px
        padding 0 8px
        height 24px
        line-height 24px
        background: rgba(0,0,0,0.2)
        font-size 10px
        border-radius 14px
        text-align: center
        .count
          vertical-align: top
        .icon-keyboard_arrow_right
          margin-left 2px
          line-height:24px

3. 公告区域的实现

  • div结构

    |-div.bulletin-wrapper
    	|-div.bulletin-title
    	|-div.bulletin-text
    	|-i.icon-keyboard_arrow_right
    
  • 使用相对定位

  • 缩略符的实现:
    超出边界部分隐藏;不使用换行;文本溢出时使用省略号代替被修剪的文字

	 white-space nowrap
     overflow hidden
     -ms-text-overflow: ellipsis
     text-overflow: ellipsis
  • bg-image($url)的实现
    目的:针对不同的dpr,显示不同尺寸大小的背景图片
    实现:在mixin.styl文件中添加该函数

    bg-image($url)
      background-image url($url + "@2x.png")
      @media (-webkit-min-device-pixel-ratio: 3), (-min-device-pixel-ratio: 3)
        background-image url($url + "@3x.png")
    
  • css布局

	.bulletin-wrapper
      /*使用相对定位*/
      position: relative
      /*宽度由内容撑开,行高实现文本垂直居中*/
      height:28px
      line-height:28px
      /*存在内部边距*/
      padding: 0 22px 0 12px
      /*以下四行实现省略符*/
      white-space nowrap
      overflow hidden
      -ms-text-overflow: ellipsis
      text-overflow: ellipsis
      /*公告区域整体背景颜色*/
      background: rgba(7,17,27,0.5)
      /*公告图标*/
      .bulletin-title
        display: inline-block
        vertical-align: top
        margin-top 7px
        width: 22px
        height:12px
        /*使用mixin中定义的bg-image($url)函数,自动对应不同dpr下的背景图片*/
        bg-image('bulletin')
        background-size 22px 12px
        background-repeat no-repeat
      .bulletin-text
        vertical-align: top
        font-size 10px
        margin 0 4px
      .icon-keyboard_arrow_right
        /*跟随公告区域绝对定位*/
        position: absolute
        font-size 10px
        right 12px
        top 8px

4. header组件整体背景图片的设置

  • 作为header下一个单独的div,跟随header绝对定位,左、上距离均为0

  • div结构

      |-div.background
      	|-img
    
  • 对于img标签,宽高均设为100%,在引入图片的时候,使用v-bind:src指令

    
    
  • 将divwidth、height设为100%,铺满父元素

  • z-index设为-1,置于底层

  • filter:blur(10px) 实现毛玻璃效果

  • css布局

	.background
      position: absolute
      top 0
      left 0
      width: 100%
      height: 100%
      /*置于底层,作为背景*/
      z-index: -1
      /*毛玻璃效果,模糊背景图片*/
      filter blur(10px)

5. 弹出层的显示与隐藏(v-show

  • v-show指令的使用:当v-show所指的字段值为false的时候,隐藏当前内容,否则显示
  • 与v-if指令的区别:v-if是根据条件直接创建或者删除一个DOM节点,而v-show指令下,只是改变元素的css中display属性为none或者block,该节点的DOM不改变
  • 给点击元素(数量按钮和公告区域)绑定click事件,事件函数showDetail的作用就是改变v-show字段的值

6. 弹出层的实现(CSS Sticky Footer)

  • 作用:当点击活动数量按钮或者公告的时候,显示商家的详细信息,包括name、star、优惠活动列表、商家公告内容

  • 关闭功能的实现:给按钮绑定click事件,值为hideDetail,作用是将detailShow的值设为false

  • div布局

     |-div.detail
     	|-div.detail-wrapper .clearfix
     		|-div.detail-main
     			|-h1
     			|-div.star-wrapper
     				|-star
     			|-div.title
     				|-div.line
     				|-div.text
     				|-div.line
     			|-ul.supports
     				|-li.support-item
     					|-span.icon
     					|-span.text
     			|-div.title
     				|-div.line
     				|-div.text
     				|-div.line
     			|-div.bulletin
     				|-p.content
     	|-div.detail-close
     		|-i.icon-close
    
  • css sctiky footer :将关闭按钮固定在弹出层的底部,与内容多少无关

  • div布局

      |-div.detail
      	|-div.detail-wrapper
      		|-div.detail-main
      	|-div.detail-close
    
  • css实现:detail-main需要设置一个padding-bottom:64px;detail-close设置一个margin:-64px auto 0 auto; clear:both(清除浮动)

	.detail
      /*固定在页面*/
      position: fixed
      /*显示在最上层*/
      z-index: 100
      /*位置*/
      top:0
      left:0
      /*大小*/
      width: 100%
      height: 100%
      /*超出页面部分自动滚动*/
      overflow: auto
      /*背景过滤器,对使用该属性的元素的所有下层元素添加滤镜,blur是高斯模糊效果*/
      backdrop-filer: blur(10px)
      opacity:1
      background rgba(7,17,27,0.8)
      .detail-wrapper
        /* 保证最小高度和视口一致 */
        min-height: 100%
        width:100%
        .detail-main
          margin-top: 64px
          /*为底部的关闭按钮留出空间*/
          padding-bottom 64px
          .name
            font-size:16px
            line-height 16px
            text-align center
            font-weight 700
            /*在star组件外层添加包裹,提高star组件的复用性*/
          .star-wrapper
            margin-top:18px
            padding:2px 0
            text-align: center
          .title
            /*flex布局实现文字两侧线条的自适应*/
            display: flex
            width 80%
            margin 28px auto 24px auto
            .line
              /*flex为1代表flex-grow:1,flex-shrink:1,flex-basis:auto,两边线条能够自动填满宽度*/
              flex 1
              position: relative;
              top: -6px
              border-bottom 1px solid rgba(255,255,255,0.2)
            .text
              padding 0 12px
              font-size: 14px
              font-weight: 700
          .supports
            width 80%
            margin 0 auto
            .support-item
              padding: 0 12px
              margin-bottom: 12px
              font-size: 0
              &:last-child
                margin-bottom: 0
              .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
          .bulletin
            width 80%
            margin 0 auto
            .content
              padding: 0 12px
              line-height 24px
              font-size:12px
      .detail-close
        position: relative
        width:32px
        height:32px
        margin:-64px auto 0 auto
        clear: both
        font-size:32px

7. star组件的开发和使用(star的size和score)

  • 从父组件接收的属性数据有score和size,使用v-bind绑定数据,使用props对象定义这两个属性,分别代表评分和星星的大小(48、36、24)

  • 组件template(注意:外层star和内层的star-item都要绑定一个动态class,使用v-for循环一个数组的时候,要用v-bind:key绑定一个代表item的唯一的值),使用v-for遍历starclasses数组,逐个渲染星星

     |-div.star :class="starType"
     	|-span.star-item :class="item" v-for="(item, index) in starClasses" :key="index"
    
  • js中定义两个计算属性:starType(星星的大小)和starClasses(每个星星的状态类on half off)

     const LENGTH = 5
     const CLS_ON = 'on'
     const CLS_HALF = 'half'
     const CLS_OFF = 'off'
     computed: {
     	starType () { return 'star-' + this.size },
     	starClasses () {
     		// 定义数组用于存放待渲染的每个星星各自的class
     		let result = []
     		// 重新计算score,score*2向下取整后,原本小数位小于5的,取当前整数的2倍,大于5的,取当前整数位2倍➕1,再除以2,最终得分为当前整数位或者当前整数位.5。如,原本score为3.2,计算后为3;原本score为4.8,计算后为4.5;原本score为4,计算后为4
     		let score = Math.floor(this.score * 2) / 2
     		// 判断是否有小数位
     		let hasDemical = score % 1 !== 0
     		 // 获取整颗的个数
           let integer = Math.floor(score)
           // 整数个完整的星星
           for (let i = 0; i < integer; i++) {
             result.push(CLS_ON)
           }
           // 如果有小数,放一个半星
           if (hasDemical) {
             result.push(CLS_HALF)
           }
           // 如果不够五颗星,用off补全
           while (result.length < LENGTH) {
             result.push(CLS_OFF)
           }
           return result
     	}
     }
    
  • css实现:共同的:每个star-item显示为行内块,除了最后一个,都有右外边距,背景图no-repeat;不同的:不同starType下star-item的宽高、背景大小、动态class下的背景图不同;

      
    
  • star组件的使用,用一个star-wrapper将star组件加以包裹,提高star组件的复用性,不受外部设置的影响
    header.vue

      

    {{seller.name}}

      css部分:使用文本居中让star-wrapper中的内容居中 .star-wrapper margin-top:18px padding:2px 0 text-align center

    8. 过渡效果的实现(transition组件)

    vue.js transition文档

    • div结构

      
      	
    • css实现

        .detail
        opacity: 1
        background: rgba(7,17,27,0.8)
         /*弹出层显示或者隐藏的过程中显示的过渡效果*/
         &.fade-enter-active, &.fade-leave-active
           transition all 0.5s
         /*定义过渡开始与结束时候的状态*/
         &.fade-enter, &.fade-leave-to
           opacity 0
           background rgba(7,17,27,0)
      

    9. flex布局实现“----xxxx----”效果

    • div结构

        |-div.title
        	|-div.line
        	|-div.text
        	|-div.line
      
    • css实现

        	.title
            /*flex布局实现文字两侧线条的自适应*/
            display: flex
            width 80%
            margin 28px auto 24px auto
            .line
              /*flex为1代表flex-grow:1,flex-shrink:1,flex-basis:auto,两边线条能够自动填满宽度*/
              flex 1
              position: relative;
              top: -6px
              border-bottom 1px solid rgba(255,255,255,0.2)
            .text
              padding 0 12px
              font-size: 14px
              font-weight: 700
      

    10. 其他布局小问题 (凑个整)

    	垂直对齐  vertical-align:top
    	两个相邻元素之间由于空格、回车符等存在空白间隙,如何处理?将字体大小设为0
    	清除浮动:给detail-wrapper所在的div添加clearfix类,作为常用的功能,在base.styl中定义该样式
    		.clearfix
    		  display inline-block
    		  &:after
    		    display block
    		    content ' '
    		    height 0
    		    line-height 0
    		    visibility hidden
    		    clear both
    

    你可能感兴趣的:(ES6,CSS,vue,前端)