Today, this article will talk about vue3 project when we need to use the rotation map, how to achieve the rotation effect through their own manual encapsulation.


Purpose: Encapsulate the multicast map components, step 1: use of infrastructure.

General steps:

  • Prepare shop-Carousel component base layout, global registration
  • Prepare the home-banner component, use the shop-Carousel component, and register it on the home page.
  • The depth effect selector overrides the default style of the shop-Carousel component

1. Shuffling figure infrastructure SRC/components/library/shop – carousel. Vue

<template> <div class='shop-carousel'> <ul class="carousel-body"> <li class="carousel-item fade"> <RouterLink to="/"> < img SRC = "" > < / RouterLink > < / li > < / ul > / / about two small button < a href =" javascript:;" class="carousel-btn prev"> <i class="iconfont icon-angle-left"></i> </a> <a href="javascript:;" Class ="carousel-btn next"> < I class="iconfont icon-angle-right"></ I ></ a> / class="carousel-indicator"> <span v-for="i in 5" :key="i"></span> </div> </div> </template> <script> export default { name: 'XtxCarousel' } </script> <style scoped lang="less"> .shop-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; The transition: 0.5 s linear opacity; &.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, 2); color: #fff; border-radius: 50%; position: absolute; top: 228px; z-index: 2; text-align: center; line-height: 44px; opacity: 0; The transition: all 0.5 s; &.prev{ left: 20px; } &.next{ right: 20px; } } } &:hover { .carousel-btn { opacity: 1; } } } </style>Copy the code

2. Global registration by figure SRC/components/library/index. Js

import ShopCarousel from './shop-carousel.vue'

export default {
  install (app) {
    app.component(ShopCarousel.name, ShopCarousel)

  }
}
Copy the code

3. The home page AD component infrastructure SRC/views/home/components/home – banner. Vue

<template>
  <div class="home-banner">
    <XtxCarousel />
  </div>
</template>
<script>
export default {
  name: 'HomeBanner'
}
</script>
<style scoped lang="less">
.home-banner {
  width: 1240px;
  height: 500px;
  position: absolute;
  left: 0;
  top: 0;
  z-index: 98
}
</style>
Copy the code

4. Use ads on your home page

<template> <! <div class="home-entry"> <div class="container"> <! <HomeBanner /> </div> </div> </template> <script> import HomeBanner from './components/home-banner' export default { name: 'HomePage', components: { HomeBanner } } </script> <style scoped lang="less"></style>Copy the code

5. Cover them by figure component style SRC/views/home/components/home – banner. Vue

.ahop-carousel { ::v-deep .carousel-btn.prev { left: 270px; } ::v-deep .carousel-indicator { padding-left: 250px; }}Copy the code
  1. Encapsulate general purpose carousel components
  2. Encapsulate the business component home-banner
  3. Customize the style of a common component in a business component (you cannot directly modify the style of a common component)

Note: it is necessary to pay attention to the overlay style, the home page rotation map has special layout requirements.

Depth selectors need to be added to the selectors of DOM elements within the component root node (component root style does not require depth selectors)

Objective: Encapsulate the carousel component. Step 2: dynamically render the structure.

General steps:

  • Define the API function for getting an AD image
  • Get the rotation chart data from the home-banner component and pass it to the shop-Carousel component
  • Complete the rendering in the Shop-Carousel component

1. Encapsulate an interface called findBanner to request data (omit code here) 2. Advertising component to get the data, to round figure SRC/views/home/components/home – banner. Vue

<template> <div class="home-banner"> <ShopCarousel :sliders="sliders" /> </div> </template> <script> import { ref } from  'vue' import { findBanner } from '@/api/home' export default { name: 'HomeBanner', setup () { const sliders = ref([]) findBanner().then(data => { sliders.value = data.result }) return { sliders } } } </script>Copy the code

3. Complete them by figure structure rendering SRC/components/library/shop – carousel. Vue

<template> <div class='shop-carousel'> <ul class="carousel-body"> <li class="carousel-item" v-for="(item,i) in sliders" :key="i" :class="{fade:index===i}"> <RouterLink to="/"> <img :src="item.imgUrl" alt=""> </RouterLink> </li> </ul> <a href="javascript:;" class="carousel-btn prev"> <i class="iconfont icon-angle-left"></i> </a> <a href="javascript:;" class="carousel-btn next"> <i class="iconfont icon-angle-right"></i> </a> <div class="carousel-indicator"> <span v-for="(item,i) in sliders" :key="i" :class="{active:index===i}"></span> </div> </div> </template> <script> import { ref  } from 'vue' export default { name: 'ShopCarousel', props: { sliders: { type: Array, default: () => []}}, setup () {const index = ref(0) return {index}} </script>Copy the code

Summary: Fade controls the display of the image, requires a default index, renders the first image and activates the first point. Objective: To encapsulate the components of the multicast diagram. Step 3: to realize the logical functions. General steps:

  • Auto play, exposed auto rotation properties, set to auto rotation
  • If there is auto play, mouse enter leave, pause, open
  • Indicator toggle, up, down
  • Destroy the components and clean up the timer

1. Automatically round realization of SRC/components/library/shop – carousel. Vue

import { ref, watch } from 'vue' export default { name: 'ShopCarousel', props: { sliders: { type: Array, default: () => []}, // Duration: {type: Number, default: 3000}, // autoPlay: {type: Boolean, default: false } }, Setup (props) {const index = ref(0) // let timer = null const autoPlayFn = () => { ClearInterval (timer) timer = setInterval(() => {index.value++ if (index.value >= functions.sliders.length) {clearInterval(timer) timer => {index.value++ if (index.value >= props. Index. Value = 0}}, props. Duration)} watch(() => props. Sliders, (newVal) => { If (newval.length > 1 && props. AutoPlay) {index. Value = 0 autoPlayFn()}}, {immediate: true }) return { index } } }Copy the code

2. If there is auto play, mouse enter leave, pause, open

// The mouse enters to stop, and moves out to turn on the auto. Prerequisites: AutoPlay is true const stop = () => {if (timer) clearInterval(timer)} const start = () => {if (props.sliders.length && props.autoPlay) { autoPlayFn() } } return { index, stop, start }Copy the code
<div class='shop-carousel' @mouseEnter ="stop()" @mouseleave="start()">Copy the code

3. Indicator switch, up, down

Const toggle = (step) => {index. Value += step if (index >= functions.sliders.length) {index. Value = 0 return} if (index < 0) { index.value = props.sliders.length - 1 return } } return { index, stop, start, toggle }Copy the code
<! On a -- -- - > < a @ click = "toggle (1)" href = "javascript:;" class="carousel-btn prev"> <i class="iconfont icon-angle-left"></i> </a> <! - the next - > < a @ click = "toggle (1)" href = "javascript:;" class="carousel-btn next"> <i class="iconfont icon-angle-right"></i> </a>Copy the code

4. Destroy components and clear timers

OnUnmounted (() => {clearInterval(timer)})Copy the code

This is the basic process of manually encapsulating a multicast diagram component. Let’s summarize it again:

Summary: according to the steps of thinking, step by step to achieve.

  1. Basic component splitting and layout
  2. Automatically round
  3. Hover controls start and stop
  4. Manual control switching
  5. Destroy timer
  6. Extract relevant parameters