目标: 完成详情页的开发

当点击首页的热销推荐中的某一项,可以进入它对应的详情页。

  1. 按照原来的思路,我们可以直接在li标签外面包裹一层<router-link to="/detail"></router-link>。 还是同样的问题,它会默认转换成一个a标签,里面的文字颜色就会被更改。在这里,我们换一种方式:直接将li变成router-link,然后再添加一个指示为li的tag属性,并动态的将页面跳转到/detail/item.id即:
<ul><router-linktag="li" class="item border-bottom" v-for="item of list" :key="item.id":to="'/detail/' + item.id"><img class="item-img" :src="item.imgUrl" ><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>
</ul>
  1. 添加路由配置:router/index.js添加一项动态路由项,即前面的路径必须是/detail,后面可以带一个参数,这个参数会放到变量id中
 {path: '/detail/:id',name: 'Detail',component: Detail
}
  1. 组件创建: pages/detail/Detail.vue

  2. 完成基础模板搭建并引入到路由的index.js中

  3. 开始进行详情页banner部分开发

    1. 创建组件并搭建基本框架:detail/components/Banner.vue
    2. 引入Detail组件并使用<detail-banner></detail-banner>
    3. 完成banner的布局与样式美化:
    <div class="banner"><img class="banner-img" src="//img1.qunarzz.com/sight/p0/1707/82/821428e3bbf93bbaa3.water.jpg_600x330_2385695d.jpg" alt=""><div class="banner-info"><div class="banner-title">迪士尼小镇</div><div class="banner-number"><span class="iconfont banner-icon"></span>39</div></div></div>
    
    .banneroverflow hiddenheight 0padding-bottom 55%position relative.banner-imgwidth 100%.banner-infoposition absoluteleft 0right 0bottom 0display flexline-height .6remcolor #fff.banner-titleflex 1font-size .36rempadding 0 .2rem.banner-numberpadding 0 .2remheight .32remline-height .32remborder-radius .2rembackground rgba(0, 0, 0, .8)font-size .24remmargin-top .14rem .banner-iconfont-size .24rem
    
    1. 添加图片的icon: 官网 —> 找到图片 —> 添加到项目 —> 下载到本地 —> 解压后需要两步操作

      1. 将项目中的src/assets/styles/iconfont下面的4个字体文件替换成download中的对应字体文件
      2. 将项目中的src/assets/styles/iconfont.css中的base64替换成download中的iconfont.css中的base64url
      3. 去官网复制对应的icon代码使用,download下来的文件就可以删除掉了
    2. banner底部一个线性渐变的效果
      给banner-infor添加一个样式:
background-image linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.8))
  1. 公用图片画廊组件拆分

当点击顶部banner的时候会弹出一个画廊组件,可以进行图片的轮播,下面会显示当前所在图片的页码,在项目中可能很多页面都会用到这样的功能效果,所以可以把它变成一个公用的组件:src/common/gallery/Gallery.vue

build/webpack.base.conf.js中添加一项别名:

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

记得改完配置项后重启服务器。

在Banner.vue中使用Gallery.vue组件:import CommonGallery from 'common/gallery/Gallery',绑定CommonGallery之后就可以使用<common-gallery></common-gallery>了。

有轮播的效果,这里也是使用swiper的那个插件,将首页中Swiper.vue的轮播部分借鉴过来,先将图片的位置固定,使其能够实现基本的轮播效果,我们希望在翻页的时候底部能够显示当前的图片页码,这里就需要设置swiper的option选项。参考这里去找到对应的paginationType分页器样式类型。即:

布局:

<div class="wrapper"><swiper :options="swiperOptions"><swiper-slide><img class="gallery-img" src="http://img1.qunarzz.com/sight/p0/1707/c2/c2be8d6326cdea1a3.water.jpg_r_800x800_97e80887.jpg" /></swiper-slide><swiper-slide><img class="gallery-img" src="http://img1.qunarzz.com/sight/p0/1707/c4/c48e92049336b8ffa3.water.jpg_r_800x800_42a54b54.jpg" /></swiper-slide><div class="swiper-pagination"  slot="pagination"></div></swiper>
</div>

样式:

.wrapperoverflow hiddenheight 0width 100%padding-bottom 100%.gallery-imgwidth 100%.swiper-paginationcolor #fff

分页器设置

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

此时会发现,分页器能够显示出来了,但是不是我们想要的位置,做一下调整:
首先将.wrapperoverflow hidden去掉,然后.swiper-pagination设置一个bottom: -1rem,然后会发现依然没有出现,是因为在.swiper-container也有一个overflow hidden限制了它的范围,所以设置:

.container >>> .swiper-containeroverflow inherit

至此,成功显示。

完成动态数据循环。图片中的src应该是动态变化的,就需要从外部传递一个数据过来,根据这个数据进行动态渲染:

props: {imgs: {type: Array,default () {return ['http://img1.qunarzz.com/sight/p0/1707/c2/c2be8d6326cdea1a3.water.jpg_r_800x800_97e80887.jpg', 'http://img1.qunarzz.com/sight/p0/1707/c4/c48e92049336b8ffa3.water.jpg_r_800x800_42a54b54.jpg']}}
}

其中,type是指这个数据的类型,default是设置的默认值。然后就可以实现循环渲染:

<swiper-slide v-for="(item, index) of imgs" :key="index"><img class="gallery-img" :src="item" />
</swiper-slide>

一般将default设置为空,从Banner中以属性的方式传递过来数据。所以需要设置Banner中的数据:

data() {return {imgs: ['http://img1.qunarzz.com/sight/p0/1707/c2/c2be8d6326cdea1a3.water.jpg_r_800x800_97e80887.jpg', 'http://img1.qunarzz.com/sight/p0/1707/c4/c48e92049336b8ffa3.water.jpg_r_800x800_42a54b54.jpg']}
}

进行一些逻辑上的实现。首先,这个图片的轮播希望能够控制它的显示和隐藏,不然那一开始的时候详情页的部分是会被遮挡的,所以,在Banner中使用这个组件的时候设置一个v-show="showGallery"来控制它的显示与隐藏效果。showGallery默认是false的,当我点击banner部分的时候希望它显示出来,所以给banner绑定一个点击事件:

methods: {handleBannerClick () {this.showGallery = true}
}

此时,点击banner的时候会发现,轮播效果出现了问题,因为一开始<common-gallery></common-gallery>是处于一个隐藏的状态,当再把它显示出来的时候,swiper计算宽度会有问题,导致轮播图无法正常滚动。解决方法: 添加两个options选项:

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

表示的是:当swiper这个插件监听到这个元素或者父元素DOM元素发生变化的时候会自动的自我刷新一次,通过这次自我更新就能解决宽度计算的问题。

当我点击gallery部分的时候希望它重新隐藏: 给container绑定一个点击事件handleGalleryClick,在Banner.vue中的<common-gallery></common-gallery>组件上监听这个事件,当监听到这个点击事件发生的时候就将this.showGallery设置为false。具体代码如下:

Gallery.vue:

<div class="container" @click="handleGalleryClick"><div class="wrapper"><swiper :options="swiperOptions"><swiper-slide v-for="(item, index) of imgs" :key="index"><img class="gallery-img" :src="item" /></swiper-slide><div class="swiper-pagination"  slot="pagination"></div></swiper> </div>
</div>
methods: {handleGalleryClick () {this.$emit('close')}
}

Banner.vue:

<common-gallery :imgs="imgs" v-show="showGallery"@close="handleBannerGallery"
></common-gallery>
handleBannerGallery () {this.showGallery = false
}
}

}


Banner.vue:
```html
<common-gallery :imgs="imgs" v-show="showGallery"@close="handleBannerGallery"
></common-gallery>
handleBannerGallery () {this.showGallery = false
}

去哪儿-16-detail-banner相关推荐

  1. 初学者如何提高跑步速度_2020年假日:您最喜欢的跑步者的16个礼物创意

    初学者如何提高跑步速度 Maridav/ShutterstockMaridav /快门 Have some friends or family members who love putting on ...

  2. (项目)在线教育平台(十二)

    十七.首页和全局404.500页面配置 1.首页配置 首页页面轮播课程需要在课程的model中添加is_banner字段,说明是否是轮播课程: 1 class Course(models.Model) ...

  3. Java多线程学习四十三:

    本课时我们主要讲解 final 的三种用法. final 的作用 final 是 Java 中的一个关键字,简而言之,final 的作用意味着"这是无法改变的".不过由于 fina ...

  4. Java多线程学习四十二:有哪些解决死锁问题的策略和哲学家就餐问题

    线上发生死锁应该怎么办 如果线上环境发生了死锁,那么其实不良后果就已经造成了,修复死锁的最好时机在于"防患于未然",而不是事后补救.就好比发生火灾时,一旦着了大火,想要不造成损失去 ...

  5. Java多线程学习四十:如何写一个必然死锁的例子

    死锁是什么?有什么危害? 什么是死锁 发生在并发中 首先你要知道,死锁一定发生在并发场景中.我们为了保证线程安全,有时会给程序使用各种能保证并发安全的工具,尤其是锁,但是如果在使用过程中处理不得当,就 ...

  6. Java多线程学习三十九:CAS 有什么缺点?

    CAS 有哪几个主要的缺点. 首先,CAS 最大的缺点就是 ABA 问题. 决定 CAS 是否进行 swap 的判断标准是"当前的值和预期的值是否一致",如果一致,就认为在此期间这 ...

  7. Java多线程学习三十八:你知道什么是 CAS 吗

    CAS 简介 CAS 其实是我们面试中的常客,因为它是原子类的底层原理,同时也是乐观锁的原理,所以当你去面试的时候,经常会遇到这样的问题"你知道哪些类型的锁"?你可能会回答&quo ...

  8. Java多线程学习三十七:volatile 的作用是什么?与 synchronized 有什么异同

    volatile 是什么 首先我们就来介绍一下 volatile,它是 Java 中的一个关键字,是一种同步机制.当某个变量是共享变量,且这个变量是被 volatile 修饰的,那么在修改了这个变量的 ...

  9. Java多线程学习三十六:主内存和工作内存的关系

    CPU 有多级缓存,导致读的数据过期 由于 CPU 的处理速度很快,相比之下,内存的速度就显得很慢,所以为了提高 CPU 的整体运行效率,减少空闲时间,在 CPU 和内存之间会有 cache 层,也就 ...

  10. Java多线程学习三十五: CyclicBarrier 和 CountDownLatch 有什么不同

    CyclicBarrier 和 CountDownLatch 有什么不同? CyclicBarrier作用 CyclicBarrier 和 CountDownLatch 确实有一定的相似性,它们都能阻 ...

最新文章

  1. matlab篮球队需要五名队员,MATLAB应用与数学欣赏.doc
  2. mysql8.0连接jdbc url_mysql8.0 jdbc连接注意事项
  3. Chipseq数据库的建立
  4. halcon学习笔记——机器视觉工程应用的开发思路
  5. 机器学习之 weka学习(四)
  6. 前端小知识点(9):函数和对象之间的关系
  7. eclipse中下载spring-tool-suite插件遇到的问题
  8. java 指定垃g1圾收集_Java知识梳理--JVM
  9. k8s kubectl生成kube-config文件
  10. Oracle 初始化参数文件pfile和spfile
  11. 聆听python之父诠释python的精神和文化
  12. uniapp实现语音识别
  13. SLAM 中evo的使用(二) (evaluation of odometry) evo_traj/ape rpe/evo_ape说明与示例
  14. 北京摇号新政发布!每人只留一指标 60%新能源指标优先无车家庭
  15. 使用windows自带的磁盘测速工具对硬盘进行测速——从此无需额外下载第三方硬盘测速工具
  16. 华为手机如何实现语音转文字?简单的很,一步步教你完成
  17. [论文写作笔记] C4以小窥大的摘要 C5 讲故事一样的引言
  18. 【Proteus仿真】51单片机+74HC164驱动两个四位数码管
  19. 我的Qt作品(5)使用Qt+Halcon实现模板匹配;支持ROI框选/橡皮擦涂抹功能
  20. [前端笔记——HTML介绍] 4.HTML文本基础+超链接+高级文本格式

热门文章

  1. Linux+Tomcat建站笔记(JDK,Mysql,Vsftpd,Iptables等配置)
  2. 人工智能 - paddlepaddle飞桨 - 深度学习基础教程 - 个性化推荐
  3. DataGuard常用命令及DG主备库开关顺序
  4. 在Mac OS X上安装Oracle客户端
  5. Docker上部署WebERP系统,开源ERP框架
  6. 【Linux系列】Linux基础知识整理
  7. 证明task线程是来源于线程池的,线程重用
  8. 【Python】Python库之图形艺术
  9. C#算法设计之知识储备
  10. C#LeetCode刷题之#581-最短无序连续子数组( Shortest Unsorted Continuous Subarray)