(19)详情页开发——① 动态路由和 Banner 组件布局 | Vue.js 项目实战: 移动端“旅游网站”开发

228 阅读4分钟
转载请注明出处,未经同意,不可修改文章内容。

🔥🔥🔥“前端一万小时”两大明星专栏——“从零基础到轻松就业”、“前端面试刷题”,已于本月大改版,合二为一,干货满满,欢迎点击公众号菜单栏各模块了解。

1 需求

❓需求 1:在首页点击“景点”(如故宫),可跳转至“景点详情页”。不同景点,跳转至不同景点的详情页(即,不同路由)。

视频01.gif

需求 2:完成详情页 Banner 的布局。

2 动态路由

需求分析:点击首页不同的景点,跳转至对应不同的详情页。即,当我们点击景点后,需要在路由上携带参数 id

1️⃣首先,我们需要新建详情页;

1️⃣-①:在 src 下的 pages 中新建 detail 文件夹;

1️⃣-②:在 detail 文件夹中新建详情页组件 Detail.vue

<template>
  <div>This is Detail.</div> <!-- 1️⃣-④:添加一点内容; -->
</template>

<script>
export default {
  name: 'Detail' // 1️⃣-③:详情页组件名为“Detail”;
}
</script>

<style>
</style>

1️⃣-⑤:然后,打开 router 下的 index.js ,添加详情页的路由;

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' // 1️⃣-⑥:引入详情页组件 Detail.vue;

Vue.use(Router)

export default new Router({
  routes: [{
    path: '/',
    name: 'Home',
    component: Home
  }, {
    path: '/city',
    name: 'City',
    component: City
  }, {
    path: '/detail/:id', /*
    										 1️⃣-⑦:详情页的路径为 /detail/ ,它后面还要跟一个 id 的参数,所以这里
                         写了一个动态路由 :id (即,前面的路由必须是 /detail/ ,后面可以携带一
                         个参数,这个参数放入 id 这个变量中);
                          */
    name: 'Detail', // 1️⃣-⑧:name 为 Detail;
    component: Detail // 1️⃣-⑨:component 为 Detail 组件;
  }]
})

1️⃣-⑩:打开 home 下 components 中的热销推荐组件 Recommend.vue

<template>
  <div>
    <div class="title">热销推荐</div>
    <ul>
      <router-link
        tag="li"
        class="item border-bottom"
        v-for="item of list"
        :key="item.id"
        :to="'/detail/' + item.id"
      > <!-- 1️⃣-⑪:使用 router-link 标签,替换原本的 li 标签,
      	1️⃣-⑫:router-link 上添加一个 tag,它的值为 li;
     		1️⃣-⑬:动态绑定 to 属性,值为 /detail/ 再带上参数 item.id(即景点的 id)。
      	❗️注意:当使用 router-link 时,Vue 会默认把它渲染为 a 标签。但,当我们添加 tag 并指定它
				为 li 时,Vue 会将这个 router-link 标签渲染为 li 标签,并同时具有 a 标签的功能。 -->
        
        <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>
  </div>
</template>

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

<style lang="stylus" scoped>
@import '~styles/mixins.styl'

.title
  margin-top: .2rem
  background: #eee
  line-height: .8rem
  text-indent: .2rem
.item
  overflow: hidden
  display: flex
  height: 1.9rem
  .item-img
    width: 1.7rem
    height: 1.7rem
    padding: .1rem
  .item-info
    flex: 1
    padding: .1rem
    min-width: 0
    .item-title
      line-height: .54rem
      font-size: .32rem
      ellipsis()
    .item-desc
      line-height: .4rem
      color: #ccc
      ellipsis()
    .item-button
      margin-top: .16rem
      line-height: .44rem
      color: #fff
      background: #ff9300
      padding: 0 .2rem
      border-radius: .06rem
</style>

保存后,返回页面查看。点击热销推荐的不同景点时,可跳转至详情页。由于路由中携带了参数,所以点击不同景点,可跳转至不同的详情页:

视频02.gif

3 Banner 组件布局

需求分析:Banner 组件主要分为“大图部分”,底部左边的“景点标题”和右边的“图片数量”,整个底部还有一个从透明到略黑的渐变色。

2️⃣在 detail 文件夹中新建一个 components 文件夹,并新建 Banner 组件 Banner.vue

<template>
  <div>
    This is DetailBanner. <!-- 2️⃣-②:添加一点内容; -->
  </div>
</template>

<script>
export default {
  name: 'DetailBanner' // 2️⃣-①:组件命名为 DetailBanner;
}
</script>

<style lang="stylus" scoped>
</style>

2️⃣-③:打开 detail 下的 Detail.vue 使用 Banner 组件;

<template>
  <div>
    <detail-banner></detail-banner> <!-- 2️⃣-⑥:使用 Banner 组件; -->
  </div>
</template>

<script>
import DetailBanner from './components/Banner' // 2️⃣-④:引入 Banner 组件;

export default {
  name: 'Detail',

  components: { // 2️⃣-⑤:在 Detail 中注册 Banner 组件;
    DetailBanner
  }
}
</script>

<style>
</style>

保存后,返回页面查看:

2️⃣-⑦:返回 detail 下 components 中的 Banner.vue 编写样式;

<template>
  <div class="banner"> <!-- 2️⃣-⑧:给最外层 div 添加类名为 banner,里边包含一个 img 标签和一
											 个 div 标签; -->

    <!-- 2️⃣-⑨:img 为“大图部分”,类名为 banner-img; -->
    <img class="banner-img" src="https://qdywxs.github.io/travel-images/detail-banner-img.jpg">

    <div class="banner-info"> <!-- 2️⃣-⑩:div 为“景点介绍”,类名为 banner-info,里边包含一
															个“景点标题 .banner-title”和一个“图片数量 .banner-number”; -->
      
      <div class="banner-title">故宫(AAAAA景区)</div>
      
      <div class="banner-number"> <!-- 2️⃣-⑪:.banner-number 中有一个 span 标签和“图片
																	数量3”,span 标签的内容是“图片图标”的 Unicode 码; -->
        <span class="iconfont banner-icon">&#xe64a;</span>
        3
      </div>
    </div>
  </div>
</template>

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

<style lang="stylus" scoped>
.banner /*
  			2️⃣-⑫:设置图片的容器 .banner 高为宽的 55% 占位,防止页面内容抖动;
  			2️⃣-⑮:设置 .banner 为相对定位;
  			 */
  position: relative
  overflow: hidden
  height: 0
  padding-bottom: 55%

  .banner-img /* 2️⃣-⑬:设置图片宽为 100%; */
    width: 100%

  .banner-info /*
  						 2️⃣-⑭:设置 .banner-info 为 flex 布局,并且绝对定位,left、right、bottom 为
  						 0,行高为 0.6rem,添加 background-image 设置 linear-gradient(从上到下进行
  						 渐变,颜色为黑色,透明度从 0 到 0.8);
  							*/
    position: absolute
    left: 0
    right: 0
    bottom: 0
    display: flex
    line-height: .6rem
    color: #fff
    background-image: linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, .8))

    .banner-title /*
  								2️⃣-⑯:设置 .banner-title 的 flex 值为 1,padding 上下为 0、
  								左右为 0.2rem,字体大小为 0.32rem,;
  								 */
      flex: 1
      padding: 0 .2rem
      font-size: .32rem

    .banner-number /*
  								 2️⃣-⑰:设置 .banner-number 的高和行高都为 0.32rem,左右 padding 
  								 为 0.4rem,设置 margin-top 为 0.14rem,字体大小设为 0.24rem、颜色为白色,
  								 添加 0.2rem 的圆角,设置背景色为透明度 0.8 的黑色;
  								  */
      height: .32rem
      padding: 0 .4rem
      margin-top: .14rem
      font-size: .24rem
      color: #fff
      line-height: .32rem
      border-radius: .2rem
      background: rgba(0, 0, 0, .8)

      .banner-icon /* 2️⃣-⑱:设置 icon 的大小为 0.24rem。 */
        font-size: .24rem
</style>

保存后,返回页面查看:

以上,我们使用了动态路由来实现首页跳转至详情页(详情页路由中的 id 将在后续通过 AJAX 动态获取详情页数据时再次用到 ),完成了详情页的 Banner 组件布局。

祝好,qdywxs ♥ you!