Method of vue3 Encapsulating Carousel Component

  • 2021-11-23 22:29:39
  • OfStack

Purpose

Encapsulate the carousel chart component and use it directly. The specific contents are as follows

Approximate steps

Prepare the basic layout of my-carousel components and register globally Prepare home-banner components, use my-carousel components, and then register for use on the home page. The depth action selector overrides the default style of my-carousel components The carousel data is obtained in the home-banner component and transmitted to the my-carousel component Rendering in my-carousel component Auto-play, expose auto-carousel attribute, set auto-carousel If there is automatic playback, the mouse enters and leaves, pauses and opens Indicator switching, top 1, bottom 1 Destroy components and clean timers

Landing code

1. Package the components


<template>
  <div class="my-carousel" @mouseenter="stop" @mouseleave="start">
    <ul class="carousel-body">
      <li v-for="(item, i) in findBannerList" :key="item.id" class="carousel-item" :class="{ fade: index === i }">
        <RouterLink to="/">
          <img :src="item.imgUrl" alt=" Picture " />
        </RouterLink>
      </li>
    </ul>
    <a @click="clickFn(-1)" href="javascript:;" class="carousel-btn prev"><i class="iconfont icon-angle-left"></i></a>
    <a @click="clickFn(1)" href="javascript:;" class="carousel-btn next"><i class="iconfont icon-angle-right"></i></a>
    <div class="carousel-indicator">
      <span @click="active(i)" v-for="(item, i) in findBannerList" :key="i" :class="{ active: index === i }"></span>
    </div>
  </div>
</template>

<script>
import { onUnmounted, ref, watch } from 'vue'
export default {
  name: 'Carousel',
  props: {
    findBannerList: {
      type: Array,
      default: () => []
    },
    autoplay: {
      type: Boolean,
      default: true
    },
    duration: {
      type: Number,
      default: 3
    }
  },
  setup(props) {
    const index = ref(0)
    //  Definition 1 Constant storage timer 
    const timer = ref(null)
    //  Timer method to realize automatic carousel effect 
    const autoplayFn = () => {
      //  Anti-shake, prevent multiple triggers of timer 
      clearInterval(timer.value)
      timer.value = setInterval(() => {
        index.value += 1
        if (index.value >= props.findBannerList.length) {
          index.value = 0
        }
      }, props.duration * 1000)
    }
    //  Listener, according to the data returned by the interface and the related property parameters passed  autoplay  Turn on carousel 
    //  The length of the data returned by listening, when the length is greater than 1 When and  autoplay  The is  true  Turn on the carousel when 
    watch(
      () => props.findBannerList,
      () => {
        if (props.findBannerList.length > 1 && props.autoplay) {
          autoplayFn()
        }
      }
    )
    //  Move the mouse into the carousel and stop playing automatically 
    const stop = () => {
      if (timer.value) clearInterval(timer.value)
    }
    //  Move the mouse out of the carousel and start the timer 
    const start = () => {
      if (props.findBannerList.length > 1 && props.autoplay) {
        autoplayFn()
      }
    }
    //  Click the left and right buttons on the carousel, switch the carousel, and decide the carousel to go left and right through the passed parameters 
    const clickFn = e => {
      index.value += e
      if (index.value >= props.findBannerList.length) {
        index.value = 0
      }
      if (index.value < 0) {
        index.value = props.findBannerList.length - 1
      }
    }
    //  Click the indicator (small dot at the bottom of the carousel) to switch the carousel 
    const active = e => {
      index.value = e
    }
    //  Love letter timer when components are destroyed to avoid performance loss 
    onUnmounted(() => {
      if (timer.value) clearInterval(timer.value)
    })
    return { index, stop, start, clickFn, active }
  }
}
</script>
<style scoped lang="less">
.my-carousel {
  width: 100%;
  height: 100%;
  min-width: 300px;
  min-height: 150px;
  position: relative;
  .carousel {
    &-body {
      width: 100%;
      height: 100%;
    }
    &-item {
      width: 100%;
      height: 100%;
      position: absolute;
      left: 0;
      top: 0;
      opacity: 0;
      transition: opacity 0.5s linear;
      &.fade {
        opacity: 1;
        z-index: 1;
      }
      img {
        width: 100%;
        height: 100%;
      }
    }
    &-indicator {
      position: absolute;
      left: 0;
      bottom: 20px;
      z-index: 2;
      width: 100%;
      text-align: center;
      span {
        display: inline-block;
        width: 12px;
        height: 12px;
        background: rgba(0, 0, 0, 0.2);
        border-radius: 50%;
        cursor: pointer;
        ~ span {
          margin-left: 12px;
        }
        &.active {
          background: #fff;
        }
      }
    }
    &-btn {
      width: 44px;
      height: 44px;
      background: rgba(0, 0, 0, 0.2);
      color: #fff;
      border-radius: 50%;
      position: absolute;
      top: 228px;
      z-index: 2;
      text-align: center;
      line-height: 44px;
      opacity: 0;
      transition: all 0.5s;
      &.prev {
        left: 20px;
      }
      &.next {
        right: 20px;
      }
    }
  }
  &:hover {
    .carousel-btn {
      opacity: 1;
    }
  }
}
</style>

2. Package as a plug-in


import MyCarousel from './my-carousel.vue'
export default {
  install(app) {
    app.component(MyCarousel.name, MyCarousel)
  }
}

3. Register globally in the entry file main. js


import { createApp } from 'vue'
import App from './App.vue'
import MyUI from './components/library'

//  The use of plug-ins, in main.js Use app.use( Plug-ins )
createApp(App).use(MyUI).mount('#app')

4. Using components in your project

Prepare the home-banner component, use the my-carousel component, and then introduce the home-banner component where carousel is used in the project. The following parameters can be set in the home-banner component

The findBannerList parameter is used as background request data to the inside of the component

autoplay parameter whether to turn on carousel, and true turns on carousel by default

duration parameter carousel dwell time interval in seconds


<template>
  <div class="home-banner">
    <MyCarousel :findBannerList="findBannerList" :autoplay="true" :duration="3" />
  </div>
</template>

Summarize

According to the train of thought and steps, it can be realized step by step.

1. Basic component splitting and layout
2. Automatic carousel
3. Hover control starts and stops
4. Manually control switching
Step 5 Destroy timers
6. Extract relevant parameters


Related articles: