Vue2.5開發去哪兒網App 詳情頁面開發


一,banner 圖的設計

1. 新建detail的路由

 

import Detail from '@/pages/detail/Detail'
......    
{
      path: '/detail',
      name: 'Detail',
      component: Detail
    }

 

Detail.vue

<template>
  <div>
    <detail-banner></detail-banner>
  </div>
</template>

<script>
import DetailBanner from './components/Banner'
export default {
  name: 'Detail',
  components: {
    DetailBanner
  }
}
</script>

<style>

</style>
View Code

新建 Banner.vue組件

<template>
  <div class="banner">
    <img src="http://img1.qunarzz.com/sight/p0/1409/19/adca619faaab0898245dc4ec482b5722.jpg_600x330_f922b488.jpg"
         class="banner-img" alt="">
    <div class="banner-info">
      <div class="banner-title">故宮(AAAAA景區)</div>
      <div class="banner-number"><span class="iconfont banner-icon">&#xe6bc;</span>39</div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'DetailBanner'
}
</script>

<style lang="stylus" scoped>
  .banner
    position relative
    overflow hidden
    height 0
    padding-bottom 55%
    .banner-img
      width 100%
    .banner-info
      position absolute
      color #ffffff
      left 0
      right 0
      bottom 0
      line-height .6rem
      background-image linear-gradient(top,rgba(0,0,0,0),rgba(0,0,0,0.8))
      display flex
      .banner-title
        font-size .32rem
        padding 0 .2rem
        flex 1
      .banner-number
        margin .14rem
        padding 0 .3rem
        line-height .4rem
        height .32rem
        font-size .24rem
        border-radius .2rem
        background rgba(0, 0, 0, 8)
        .banner-icon
          font-size .24rem
          padding .02rem
</style>
View Code

二,公用圖片畫廊組件

1. 創建一個公用組件 Gallary.vue

使用  vue-awesome-swiper 完成圖片滾動

<template>
  <div class="container" @click="HandleClick">
    <div class="wrapper">
      <swiper :options="swiperOption">
        <!-- slides -->
        <swiper-slide v-for="(item,index) in imgs" :key="index">
          <img class="gallery-img" :src="item" alt="">
        </swiper-slide>
        <!-- Optional controls -->
        <div class="swiper-pagination"  slot="pagination"></div>
      </swiper>
    </div>
  </div>
</template>

<script>
export default {
  name: 'CommonGallary',
  props: {
    imgs: {
      type: Array
    }
  },
  methods: {
    HandleClick () {
      // 關閉
      this.$emit('close')
    }
  },
  data () {
    return {
      swiperOption: {
        loop: true,
        pagination: '.swiper-pagination',
        paginationType: 'fraction',
        // observer啟動動態檢查器(OB/觀眾/觀看者),當改變swiper的樣式(例如隱藏/顯示)或者修改swiper的子元素時,自動初始化swiper。
        // 默認false
        observer: true,
        observeParents: true
      }
    }
  }
}
</script>

<style lang="stylus" scoped>
  .container >>> .swiper-container
    overflow inherit
  .container
    display flex
    flex-direction column
    justify-content: center
    background-color #000
    position fixed
    top 0
    left 0
    right 0
    bottom 0
    z-index 999
    .wrapper
      padding-bottom 100%
      height 0
      width 100%
      .gallery-img
        width 100%
      .swiper-pagination
        color #fff
        bottom -1rem
</style>
View Code

2. Banner.vue

定義變量   showGallary 負責照片牆的顯示與否

<common-gallary @close="HandleClose" :imgs="imgs" v-show="showGallary"></common-gallary>
監聽變化,傳入圖片數據,顯示與否
<template>
  <div>
    <div class="banner">
      <img v-show="!showGallary" @click="handleImgClick" src="http://img1.qunarzz.com/sight/p0/1409/19/adca619faaab0898245dc4ec482b5722.jpg_600x330_f922b488.jpg"
           class="banner-img" alt="">
      <div class="banner-info">
        <div class="banner-title">故宮(AAAAA景區)</div>
        <div class="banner-number"><span class="iconfont banner-icon">&#xe6bc;</span>39</div>
      </div>
    </div>
    <common-gallary @close="HandleClose" :imgs="imgs" v-show="showGallary"></common-gallary>
  </div>
</template>

<script>
import CommonGallary from 'common/gallary/Gallary'
export default {
  name: 'DetailBanner',
  data () {
    return {
      imgs: [
        'http://img1.qunarzz.com/sight/p0/1510/8e/8eea8eb6f41698290.img.jpg_r_800x800_83a5fe3a.jpg',
        'http://img1.qunarzz.com/sight/p0/1510/ca/ca60a080020329ef90.img.jpg_350x240_9ff2208e.jpg',
        'http://img1.qunarzz.com/sight/p0/1510/cc/ccafbdaac21bdbf790.img.jpg_350x240_c35f8451.jpg'
      ],
      showGallary: false
    }
  },
  methods: {
    handleImgClick () {
      this.showGallary = true
    },
    HandleClose () {
      this.showGallary = false
    }
  },
  components: {
    CommonGallary
  }
}
</script>

<style lang="stylus" scoped>
  .banner
    position relative
    overflow hidden
    height 0
    padding-bottom 55%
    .banner-img
      width 100%
    .banner-info
      position absolute
      color #ffffff
      left 0
      right 0
      bottom 0
      line-height .6rem
      background-image linear-gradient(top,rgba(0,0,0,0),rgba(0,0,0,0.8))
      display flex
      .banner-title
        font-size .32rem
        padding 0 .2rem
        flex 1
      .banner-number
        margin .14rem
        padding 0 .3rem
        line-height .4rem
        height .32rem
        font-size .24rem
        border-radius .2rem
        background rgba(0, 0, 0, 8)
        .banner-icon
          font-size .24rem
          padding .02rem
</style>
View Code

 

 

三,header 漸隱漸現效果

后退符號制作:

 

    <router-link tag="div" to="/" class="header-abs">
      <div class="iconfont back-icon header-abs-back">&#xe606;</div>
    </router-link>

 

顯示詳情:

    <div class="header-fixed" v-show="!showAbs">
      <router-link to="/">
        <div class="iconfont back-icon header-fixed-back">&#xe606;</div>
      </router-link>
      景點詳情
    </div>

 

當下滑一定距離,header-fixed 顯示出來

添加綁定滾動事件

  methods: {
    handleScroll () {
      console.log(document.documentElement.scrollTop)
    }
  },
  activated () {
    window.addEventListener('scroll', this.handleScroll)
  }

 

當滾動> 60 時,顯示出來

    handleScroll () {
      const top = document.documentElement.scrollTop
      if (top > 60) {
        this.showAbs = false
      } else {
        this.showAbs = true
      }
    }

漸隱漸現制作:

opacityStyle // 漸隱漸現變量
給header-fixed綁定 :style="opacityStyle"
handleScroll () {
      const top = document.documentElement.scrollTop
      if (top > 60) {
        let opacity = top / 140
        opacity = opacity > 1 ? 1 : opacity
        this.opacityStyle = { opacity }
        this.showAbs = false
      } else {
        this.showAbs = true
      }
    }

<template>
  <div>
    <router-link v-show="showAbs" tag="div" to="/" class="header-abs">
      <div class="iconfont back-icon header-abs-back">&#xe606;</div>
    </router-link>
    <div class="header-fixed" v-show="!showAbs"  :style="opacityStyle">
      <router-link to="/">
        <div class="iconfont back-icon header-fixed-back">&#xe606;</div>
      </router-link>
      景點詳情
    </div>
  </div>
</template>

<script>
export default {
  name: 'DetailHeader',
  data () {
    return {
      showAbs: true,
      opacityStyle: {
        opacity: 0
      }
    }
  },
  methods: {
    handleScroll () {
      const top = document.documentElement.scrollTop
      if (top > 60) {
        let opacity = top / 140
        opacity = opacity > 1 ? 1 : opacity
        this.opacityStyle = { opacity }
        this.showAbs = false
      } else {
        this.showAbs = true
      }
    }
  },
  activated () {
    window.addEventListener('scroll', this.handleScroll)
  }
}
</script>

<style lang="stylus" scoped>
  @import "~styles/varibles.styl"
  .header-abs
    position: absolute
    left .2rem
    top .2rem
    width .8rem
    height .8rem
    line-height .8rem
    border-radius .4rem
    text-align center
    background rgba(0,0,0,.8)
    .header-abs-back
      color #ffffff
      font-size .4rem
  .header-fixed
    position fixed
    top 0
    left 0
    right 0
    overflow hidden
    height $headerHeight
    line-height $headerHeight
    color #ffffff
    background $bgColor
    text-align center
    font-size .32rem
    .header-fixed-back
      color #ffffff
      position absolute
      top 0
      left 0
      width .64rem
</style>
Header.vue

四,對全局事件解綁

因為綁定了  window.addEventListener(......)

對其他組件也產生影響

  activated () {
    window.addEventListener('scroll', this.handleScroll)
  },
  // 解綁 deactivated () { window.removeEventListener(
'scroll', this.handleScroll) }
生命周期函數:
activated
  keep-alive組件激活時調用。
  該鈎子在服務器端渲染期間不被調用。
deactivated
  keep-alive組件停用時調用。
  該鈎子在服務端渲染期間不被調用

 

五,遞歸組件實現詳情頁列表

例如有以下數據:

      list: [
        {
          title: '成人票',
          children: [
            {
              title: '特惠雙人票'
            },
            {
              title: '三人票',
              children: [
                {
                  title: '包午餐三人票'
                }
              ]
            }
          ]
        },
        {
          title: '學生票',
          children: [
            {
              title: '學生票七日游'
            }
          ]
        },
        {
          title: '兒童票'
        },
        {
          title: '特惠票'
        }
      ]

新建LIst.vue

   <div class="item" v-for="(item,index) in list" :key="index">
     <div class="item-title border-bottom">
       <span class="item-title-icon"></span>
       {{item.title}}
     </div>
     <div v-if="item.children" class="children">
// 多層遍歷 <detail-list :list="item.children"></detail-list> </div> </div>
<template>
  <div>
   <div class="item" v-for="(item,index) in list" :key="index">
     <div class="item-title border-bottom">
       <span class="item-title-icon"></span>
       {{item.title}}
     </div>
     <div v-if="item.children" class="children">
       <detail-list :list="item.children"></detail-list>
     </div>
   </div>
  </div>
</template>

<script>
export default {
  name: 'DetailList',
  props: {
    list: Array
  }
}
</script>

<style lang="stylus" scoped>
  .item-title
    line-height .8rem
    font-size .32rem
    padding 0 .2rem
  .item-title-icon
    display: inline-block;
    width: .36rem;
    height: .36rem;
    background: url(http://s.qunarzz.com/piao/image/touch/sight/detail.png) 0 -.45rem no-repeat;
    margin-right: .1rem;
    background-size: .4rem 3rem
    position relative
    left .06rem
    top: .06rem
  .children
    padding 0 .5rem
</style>
List.vue

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM