Vue3.0 handwritten carousel effect

Vue3.0 handwritten carousel effect

This article shares the specific code of Vue3.0 handwritten carousel effect for your reference. The specific content is as follows

Let's start

HTML structure

<template>
  <div class="xtx-carousel" @mouseleave="enterFn" @mouseenter="leaveFn">
    <ul class="carousel-body">
      <li class="carousel-item" :class="{ fade: indexid === index }" v-for="(item, index) in list" :key="item.id">
        <RouterLink to="/">
          <img :src="item.imgUrl" alt="" />
        </RouterLink>
      </li>
    </ul>
    <a href="javascript:;" class="carousel-btn prev" @click="lastPage"><i class="iconfont icon-angle-left"></i></a>
    <a href="javascript:;" class="carousel-btn next" @click="nextPage"><i class="iconfont icon-angle-right"></i></a>
    <div class="carousel-indicator">
      <span @click="indexid = i - 1" v-for="i in list.length" :key="i" :class="{ active: indexid === i - 1 }"></span>
    </div>
  </div>
</template>

js syntax

<script>
import { ref, watch, onUnmounted } from 'vue'
export default {
  name: 'Carousel',
  props: {
    // Image data list: {
      type: Object,
      default: () => {}
    },
    // Duration of each switching event of the carousel: {
      type: Number,
      default: 2
    },
    // Whether to enable autoplay of carousel: {
      type: Boolean,
      default: true
    },
    // Click to turn several pages: {
      type: Number,
      default: 1
    }
  },
  setup(props) {
    // Index const indexid = ref(0)
    // Carousel const timer = ref(null)
    const TimeFn = () => {
      clearInterval(timer)
      // Clear the previous timer before each execution timer.value = setInterval(() => {
        indexid.value++
        // If it exceeds the limit, refill if (indexid.value > props.list.length - 1) {
          indexid.value = 0
        }
      }, props.duration * 1000)
    }
    // Click + next stop picture const nextPage = () => {
      indexid.value += props.page
      if (indexid.value > props.list.length - 1) {
        indexid.value = 0
      }
    }
    // Click + previous picture const lastPage = () => {
      indexid.value -= props.page
      if (indexid.value < 0) {
        indexid.value = props.list.length - 1
      }
    }
    // Clear timer const leaveFn = () => {
      // console.log('clear timer')
      clearInterval(timer.value)
      // console.log(timer)
    }
    // Component consumption, cleanup timer onUnmounted(() => {
      clearInterval(timer.value)
    })
    // Start the timer const enterFn = () => {
      if (props.list.length > 1 && props.autoplay) {
        // console.log('Start timer')
        TimeFn()
      }
    }
    watch(
      () => props.list,
      () => {
        if (props.list.length > 1 && props.autoplay) {
          TimeFn()
        }
      }
    )
    return { indexid, leaveFn, enterFn, nextPage, lastPage }
  }
}
</script>

CSS Styles

<style scoped lang="less">
.xtx-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>

Register as a global plugin

import Carousel from '../carousel.vue'
// Vue2.0 plugin writing elements: export an object, have install function, pass in Vue constructor by default, extend Vue based on // Vue3.0 plugin writing elements: export an object, have install function, pass in app application instance by default, extend app based on export default {
  install(app) {
    // Expand on app, app provides component directive function // If you want to mount the prototype app.config.globalProperties method app.component(Carousel.name, xtxCarousel)
  }
}

Mount in main.js entry file

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import libraryUI from '@/components/library/index' //own plugin createApp(App)
  .use(store)
  .use(router)
  .use(libraryUI) // Mount the plugin.mount('#app')

How to use the plugin?

<Carousel :list="list" duration="1" />

The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM.

You may also be interested in:
  • How to encapsulate the carousel component in Vue3
  • vue+rem custom carousel effect
  • Sample code of uniapp vue and nvue carousel components

<<:  Solution to the failure of entering the container due to full docker space

>>:  Tips for adding favicon to a website: a small icon in front of the URL

Recommend

How to use Linux commands in IDEA

Compared with Windows system, Linux system provid...

Pure CSS3 mind map style example

Mind Map He probably looks like this: Most of the...

Importance of background color declaration when writing styles

As the title says, otherwise when the page is revi...

Several ways to manually implement HMR in webpack

Table of contents 1. Introduction 2. GitHub 3. Ba...

Writing a rock-paper-scissors game in JavaScript

This article shares the specific code for writing...

7 useful new TypeScript features

Table of contents 1. Optional Chaining 2. Null va...

MySQL 8.0.11 MacOS 10.13 installation and configuration method graphic tutorial

The process of installing MySQL database and conf...

Vue component encapsulates sample code for uploading pictures and videos

First download the dependencies: cnpm i -S vue-uu...

How to add Nginx to system services in CentOS7

Introduction After compiling, installing and solv...

How to change MySQL character set utf8 to utf8mb4

For MySQL 5.5, if the character set is not set, t...