zoukankan      html  css  js  c++  java
  • Vue2.5 旅游项目实例19 详情页 动态路由及banner布局

    创建分支:detail-banner

    拉取到本地并切换分支:

    git pull
    git checkout detail-banner

    打开home下的Recommend.vue文件:

    <router-link tag="li" class="item border-bottom"
         :to="'/detail/' + item.id"
         v-for="item in recommendList" :key="item.id">
          <img class="item-img" :src="item.imgUrl" alt="" />
          <div class="item-info">
            <p class="item-title">{{item.title}}</p>
            <p class="item-desc">{{item.desc}}</p>
            <button class="item-button">查看详情</button>
          </div>
    </router-link>

    然后新建detail文件夹下的Dettail.vue文件,并创建路由:

    import Vue from 'vue'
    import Router from 'vue-router'
    import Home from '@/pages/home/Home'
    import City from '@/pages/city/City'
    import Detail from '@/pages/detail/Detail'
    
    Vue.use(Router)
    
    export default new Router({
      routes: [
        {
          path: '/',
          name: 'Home',
          component: Home
        },
        {
          path: '/city',
          name: 'City',
          component: City
        },
        {
          path: '/detail/:id',
          name: 'Detail',
          component: Detail
        }
      ]
    })

    在detail目录下创建components文件夹,新建Banner.vue文件:

    <template>
    <div>
      banner
    </div>
    </template>
    
    <script>
    export default {
      name: 'DetailBanner'
    }
    </script>
    
    <style lang="stylus" scoped>
    
    </style>

    然后在Detail.vue中引用banner组件:

    <template>
    <div>
      <detail-banner></detail-banner>
    </div>
    </template>
    
    <script>
    import DetailBanner from './components/Banner'
    export default {
      name: 'Detail',
      components: {
        DetailBanner
      }
    }
    </script>

    继续编辑Banner.vue文件:

    <template>
    <div class="banner">
      <img class="banner-img" src="//img1.qunarzz.com/sight/p0/1409/19/adca619faaab0898245dc4ec482b5722.jpg_600x330_f922b488.jpg" />
      <div class="banner-info">
        <div class="banner-title">故宫(AAAAA景区)</div>
        <div class="banner-number"><i class="iconfont banner-icon">&#xe692;</i> 12</div>
      </div>
    </div>
    </template>
    
    <script>
    export default {
      name: 'DetailBanner'
    }
    </script>
    
    <style lang="stylus" scoped>
    .banner
      overflow: hidden
      height:0
      padding-bottom: 55%
      position: relative
      .banner-img
         100%
      .banner-info
        display:flex
        position:absolute
        left:0
        right:0
        bottom: 0
        line-height:.6rem
        color: #fff
        background-image:linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,0.8))
        .banner-title
          flex: 1
          padding:0 .2rem
          font-size: .32rem
        .banner-number
          margin-top:.14rem
          padding:0 .4rem
          line-height: .32rem
          height: .32rem
          font-size: .24rem
          border-radius:.2rem
          background:rgba(0, 0, 0, .8)
          .banner-icon
            font-size:.24rem
    </style>

    效果图:

    然后我们想要的效果是,点击顶部banner的时候,弹出一个画廊组件,这个组件里可以实现图片的轮播,图片下面还有当前图片的页码。

    公用图片画廊组件拆分

    在src目录下创建common文件夹,里面存放一些全局公用的组件。

    在common目录下创建gallary文件夹,新建Gallary.vue文件:

    <template>
    <div>gallary</div>
    </template>
    
    <script>
    export default {
      name: 'CommonGallary'
    }
    </script>
    
    <style lang="stylus" scoped>
    
    </style>

    然后打开build目录下的webpack.base.conf.js文件,添加一个别名:

    resolve: {
        extensions: ['.js', '.vue', '.json'],
        alias: {
          'vue$': 'vue/dist/vue.esm.js',
          '@': resolve('src'),
          'styles': resolve('src/assets/styles'),
          'common': resolve('src/common'),
        }
    },

    保存后,记得重启服务。

    继续打开Banner.vue文件,引用gallary组件:

    <template>
    <div>
      <div class="banner">
        <img class="banner-img" src="//img1.qunarzz.com/sight/p0/1409/19/adca619faaab0898245dc4ec482b5722.jpg_600x330_f922b488.jpg" />
        <div class="banner-info">
          <div class="banner-title">故宫(AAAAA景区)</div>
          <div class="banner-number"><i class="iconfont banner-icon">&#xe692;</i> 12</div>
        </div>
      </div>
      <common-gallary></common-gallary>
    </div>
    </template>
    
    <script>
    import CommonGallary from 'common/gallary/Gallary'
    export default {
      name: 'DetailBanner',
      components: {
        CommonGallary
      }
    }
    </script>

    然后就要继续编写Gallary.vue文件:

    先写死图片看效果:

    <template>
    <div class="container">
      <div class="wrapper">
        <swiper :options="swiperOptions">
          <swiper-slide >
            <img width="100%" src="http://img1.qunarzz.com/sight/p0/1409/19/adca619faaab0898245dc4ec482b5722.jpg_r_800x800_6edd8174.jpg" />
          </swiper-slide>
          <swiper-slide >
            <img width="100%" src="http://img1.qunarzz.com/sight/p0/1907/ca/ca68bd95bc36bdba3.img.jpg_r_800x800_33169c4b.jpg" />
          </swiper-slide>
          <div class="swiper-pagination"  slot="pagination"></div>
        </swiper>
      </div>
    </div>
    </template>
    
    <script>
    export default {
      name: 'CommonGallary',
      data () {
        return {
          swiperOptions: {
            pagination: '.swiper-pagination'
          }
        }
      }
    }
    </script>
    
    <style lang="stylus" scoped>
    .container
      display:flex
      flex-direction:column
      justify-content:center
      z-index: 99
      position: fixed
      left:0
      right:0
      top:0
      bottom:0
      background: #000
      .wrapper
         100%
        height: 0
        padding-bottom: 66%
    </style>

    这时2张图片可以滚动,下面要添加底部的分页效果:

    <script>
    export default {
      name: 'CommonGallary',
      data () {
        return {
          swiperOptions: {
            pagination: '.swiper-pagination',
            paginationType: 'fraction'
          }
        }
      }
    }
    </script>
    
    <style lang="stylus" scoped>
    .container >>> .swiper-container
      overflow:inherit
    
        .swiper-pagination
          color: #fff
          bottom: -1rem
    </style>

    现在效果就可以实现了:

    然后就可以实现循环逻辑部分了:

    <template>
    <div class="container">
      <div class="wrapper">
        <swiper :options="swiperOptions">
          <swiper-slide v-for="(item, index) in imgs" :key="index">
            <img width="100%" :src="item" />
          </swiper-slide>
          <div class="swiper-pagination"  slot="pagination"></div>
        </swiper>
      </div>
    </div>
    </template>
    
    <script>
    export default {
      name: 'CommonGallary',
      props: {
        imgs: {
          tpye: Array,
          // 默认函数,返回数组
          default () {
            return [
              'http://img1.qunarzz.com/sight/p0/1409/19/adca619faaab0898245dc4ec482b5722.jpg_r_800x800_6edd8174.jpg',
              'http://img1.qunarzz.com/sight/p0/1907/ca/ca68bd95bc36bdba3.img.jpg_r_800x800_33169c4b.jpg']
          }
        }
      },
      data () {
        return {
          swiperOptions: {
            pagination: '.swiper-pagination',
            paginationType: 'fraction'
          }
        }
      }
    }
    </script>

    效果和刚才还是一样的,没问题。

    然后把默认 default 函数,返回改为空数组。

    default () {
            return []
      }

    回到Banner.vue文件,把刚才的2个图片地址先写上:

    <common-gallary :imgs="imgs"></common-gallary>
    
    <script>
    import CommonGallary from 'common/gallary/Gallary'
    export default {
      name: 'DetailBanner',
      components: {
        CommonGallary
      },
      data () {
        return {
          imgs: ['http://img1.qunarzz.com/sight/p0/1409/19/adca619faaab0898245dc4ec482b5722.jpg_r_800x800_6edd8174.jpg', 'http://img1.qunarzz.com/sight/p0/1907/ca/ca68bd95bc36bdba3.img.jpg_r_800x800_33169c4b.jpg']
        }
      }
    }
    </script>

    刷新,效果还是一样的。

    下面我们把 common-gallary 组件设置为默认隐藏的,当点击banner的时候才会显示:

    <div class="banner" @click="handleBanner">
    、、、
    </div>
    <common-gallary :imgs="imgs" v-show="showGallary"></common-gallary>
    
    <script>
    import CommonGallary from 'common/gallary/Gallary'
    export default {
      name: 'DetailBanner',
      components: {
        CommonGallary
      },
      data () {
        return {
          showGallary: false,
          imgs: ['http://img1.qunarzz.com/sight/p0/1409/19/adca619faaab0898245dc4ec482b5722.jpg_r_800x800_6edd8174.jpg', 'http://img1.qunarzz.com/sight/p0/1907/ca/ca68bd95bc36bdba3.img.jpg_r_800x800_33169c4b.jpg']
        }
      },
      methods: {
        handleBanner () {
          this.showGallary = true
        }
      }
    }
    </script>

    现在点击banner图片时,可以显示画廊组件了,但是轮播好像滚动有点问题。这个是因为 common-gallary 组件开始是处于隐藏状态,当再次显示时,Swiper计算宽度会有一些问题,导致轮播图无法正常滚动。

    打开Gallary.vue文件,添加2个参数:

    observeParents:observe应用于Swiper的父元素。当Swiper的父元素变化时,例如window.resize,Swiper更新。

    observer:启动动态检查器(OB/观众/观看者),当改变swiper的样式(例如隐藏/显示)或者修改swiper的子元素时,自动初始化swiper。 默认false,不开启,可以使用update()方法更新。

    data () {
        return {
          swiperOptions: {
            pagination: '.swiper-pagination',
            paginationType: 'fraction',
            observeParents: true,
            observer: true
          }
        }
      }

    OK,回到页面重新刷新,已经可以滚动了。

    最后就是点击轮播图,轮播插件给关闭

    打开Gallary.vue,给container添加一个点击事件:

    <div class="container" @click="handleGallary">
    
    <script>
    export default {
      methods: {
        handleGallary () {
          this.$emit('close')
        }
      }
    }
    </script>

    在Banner.vue中接收close:

    <common-gallary :imgs="imgs" v-show="showGallary" @close="gallaryClose"></common-gallary>
    
    <script>
    import CommonGallary from 'common/gallary/Gallary'
    export default {
      methods: {
        gallaryClose () {
          this.showGallary = false
        }
      }
    }
    </script>

    OK,功能完成,可以提交代码了:

    git add .
    git commit -m "banner及公用画廊组件"
    git push
    
    git checkout master
    git merge detail-banner
    git push
  • 相关阅读:
    提高自己应用性能的总结架构篇
    iOS 开发调试技巧
    iOS (UIButton封装)仿糯米首页缩放“按钮”效果
    计算机网络中的TCP/UDP协议到底是怎么回事(二)
    计算机网络中的TCP/UDP协议到底是怎么回事(一)
    iOS一分钟学会环形进度条
    View Controller 视图管理总结
    iOS-自定义导航栏后侧滑返回功能失效
    iOS缓存框架-PINCache解读
    YYCache 设计思路
  • 原文地址:https://www.cnblogs.com/joe235/p/12507276.html
Copyright © 2011-2022 走看看