12. Vue project-detail page dynamic routing, banner layout and public picture gallery component split

I am a little caiji, but Xiaocaiji wants to continue to learn new things. Come on in the new week! ! !

Configure dynamic routing

Insert picture description here
Create a new detail folder and write the basic content in Detail.vue

Insert picture description here
Find the Recommend.vue component under the home folder, you need to add it on the li tagrouter-link声明式导航携带参数跳转页面
在这里插入图片描述

banner.vue

The important thing to note here is that when introducing new iconfont icons, you need to replace the four in the iconfont folder with new ones. One of the url (base64) in iconfont.css is also copied and replaced with a new one, so that the newly downloaded icon Will generate

Add a gradient
background-image to the class name banner-info : linear-gradient(top,rgba(0,0,0,0),rgba(0,0,0,0.8));
Insert picture description here

<template>
  <div class="banner">
    <img
      class="banner-img"
      src="//img1.qunarzz.com/sight/201406/23/57bf93474047fe36c8d65eac.jpg_600x330_76157d99.jpg"
    />
    <div class="banner-info">
      <div class="banner-title">大连圣亚海洋世界(AAAA景区)</div>
      <div class="banner-number">
        <span class="iconfont banner-icon">&#xe62d;</span>
        39
      </div>
    </div>
  </div>
</template>

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

<style lang="scss" scoped>
.banner {
     
     
  overflow: hidden;
  height: 0;
  padding-bottom: 50%;
  position: relative;
  .banner-img {
     
     
    width: 100%;
  }
  .banner-info {
     
     
    display: flex;
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    line-height: 0.6rem;
    color: #fff;
    background-image: linear-gradient(top,rgba(0,0,0,0),rgba(0,0,0,0.8));
    .banner-title {
     
     
      flex: 1;
      font-size: 0.32rem;
      padding: 0 0.2rem;
    }
    .banner-number {
     
     
      height: 0.4rem;
      line-height: 0.4rem;
      margin-top: 0.1rem;
      padding: 0 0.32rem;
      border-radius: 0.2rem;
      background: rgba(0, 0, 0, 0.6);
      font-size: 0.24rem;
      .banner-icon{
     
     
        margin-right: 0.1rem;
      }
    }
  }
}
</style>

Insert picture description here

Common picture gallery component split

Create a new common folder under src

The gallery component may be needed for other pages in the future, so turn it into a global public component, and create a new common folder under src

Insert picture description here
Go to the bulid folder to modify the path, and remember to restart the server npm run dev after the modification, the webpack modification will take effect

Insert picture description here

Use the Gallary component in banner.vue

Insert picture description here

Gallary.vue

Need to join the carousel picture.
At the time, the download was swiper3, so read the API document of swiper3.
Address: https://3.swiper.com.cn/api/pagination/2016/0126/299.html
paginationType:'fraction' attribute Make what we need this time

Insert picture description here
Insert picture description here
for loop picture, parent pass child, child component receive array

Insert picture description here
Banner.vue parent component to pass data

Insert picture description here

Browsing results found that there is a problem with swiper
Insert picture description here

Cause of the problem:
At first, the common-gallary component was hidden. When it is displayed again, the width calculated by swiper will have some problems, causing the carousel to not scroll normally.

Solution:
Address: https://3.swiper.com.cn/api/Observer/2015/0308/219.html The
swiper plug-in will automatically refresh itself once it detects changes in the Dom element of the child component or parent component , The swiper width calculation problem will be solved by self-refresh
Insert picture description here

The outermost div of Gallary.vue and Banner.vue add click events respectively

Insert picture description here

Insert picture description here
Gallary.vue

<template>
  <div class="container" @click="handleGallaryClick">
    <div class="wrapper">
      <swiper :options="swiperOption">
        <swiper-slide v-for="(item, index) in imgs" :key="index">
          <img class="gallary-img" :src="item" />
        </swiper-slide>
        <!-- 用于分页 -->
        <div class="swiper-pagination" slot="pagination"></div>
      </swiper>
    </div>
  </div>
</template>

<script>
export default {
     
     
  name: 'CommonGallary',
  props: {
     
     
    imgs: Array
  },
  data() {
     
     
    return {
     
     
      swiperOption: {
     
     
        pagination: '.swiper-pagination',
        paginationType: 'fraction',
        observer: true,
        observeParents: true
      }
    }
  },
  methods: {
     
     
    handleGallaryClick() {
     
     
      this.$emit('close')
    }
  }
}
</script>

<style lang="scss" scoped>
.container >>> .swiper-container {
     
     
  overflow: inherit;
}
.container {
     
     
  display: flex;
  flex-direction: column;
  justify-content: center;
  z-index: 99;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: #000;
  .wrapper {
     
     
    height: 0;
    width: 100%;
    padding-bottom: 100%;
    .gallary-img {
     
     
      width: 100%;
    }
    .swiper-pagination {
     
     
      color: #fff;
      bottom: -0.8rem;
    }
  }
}
</style>

Banner.vue

<template>
  <div>
    <div class="banner" @click="handleBannerClick">
      <img
        class="banner-img"
        src="//img1.qunarzz.com/sight/201406/23/57bf93474047fe36c8d65eac.jpg_600x330_76157d99.jpg"
      />
      <div class="banner-info">
        <div class="banner-title">大连圣亚海洋世界(AAAA景区)</div>
        <div class="banner-number">
          <span class="iconfont banner-icon">&#xe62d;</span>
          39
        </div>
      </div>
    </div>
    <common-gallary :imgs="imgs" v-show="showGallay" @close="handleGallaryClose"></common-gallary>
  </div>
</template>

<script>
import CommonGallary from 'common/gallary/Gallary'
export default {
     
     
  name: 'DetailBanner',
  data() {
     
     
    return {
     
     
      showGallay: false,
      imgs: [
        'http://img1.qunarzz.com/sight/p0/1503/b9/b9a4593c73228f9c.water.jpg_r_800x800_fa55893f.jpg',
        'http://img1.qunarzz.com/sight/p0/1411/a3/a4fd8afc9123ba0e0253d80e473b2185.water.jpg_r_800x800_a9b4d0f2.jpg'
      ]
    }
  },
  methods:{
     
     
    handleBannerClick(){
     
     
      this.showGallay = true
    },
    handleGallaryClose (){
     
     
      this.showGallay = false
    }
  },
  components: {
     
     
    CommonGallary
  }
  
}
</script>

<style lang="scss" scoped>
.banner {
     
     
  overflow: hidden;
  height: 0;
  padding-bottom: 50%;
  position: relative;
  .banner-img {
     
     
    width: 100%;
  }
  .banner-info {
     
     
    display: flex;
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    line-height: 0.6rem;
    color: #fff;
    background-image: linear-gradient(
      top,
      rgba(0, 0, 0, 0),
      rgba(0, 0, 0, 0.8)
    );
    .banner-title {
     
     
      flex: 1;
      font-size: 0.32rem;
      padding: 0 0.2rem;
    }
    .banner-number {
     
     
      height: 0.4rem;
      line-height: 0.4rem;
      margin-top: 0.1rem;
      padding: 0 0.32rem;
      border-radius: 0.2rem;
      background: rgba(0, 0, 0, 0.6);
      font-size: 0.24rem;
      .banner-icon {
     
     
        margin-right: 0.1rem;
      }
    }
  }
}
</style>

Guess you like

Origin blog.csdn.net/weixin_45811256/article/details/109443336