手动封装组件:轮播图

133 阅读1分钟

知识点:props、state、v-for循环渲染、事件回调函数、定时器的注册和清除。

页面结构

<template>
  <div class="xtx-carousel" @mouseenter="stopPlay" @mouseleave="startPlay">
    <ul class="carousel-body">
      <li class="carousel-item" :class="{ fade: index === currentId }" v-for="(item, index) in slides" :key="item.id">
        <RouterLink to="/">
          <img :src="item.imgUrl" alt="" />
        </RouterLink>
      </li>
    </ul>
    <a href="javascript:;" class="carousel-btn prev" @click="hPrevPic"><i class="iconfont icon-angle-left"></i></a>
    <a href="javascript:;" class="carousel-btn next" @click="hNextPic"><i class="iconfont icon-angle-right"></i></a>
    <div class="carousel-indicator">
      <span :class="{ active: index === currentId }" v-for="(item, index) in slides" :key="item.id" @click="switchToHere(index)"></span>
    </div>
  </div>
</template>

三个props。slides/autoPlay/duration。

// props slides/autoPlay/duration
const { slides, autoPlay = true, duration = 2000 } = defineProps<{
  slides: BannerItem[]
  autoPlay?: Boolean
  duration?: number
}>()

一个state。currentId。

const currentId = ref(0)

组件内部一些事件回调函数。

// 事件回调
const hNextPic = () => {
  currentId.value = (currentId.value + 1) % slides.length
}

const hPrevPic = () => {
  // ?如何用取余的方式书写
  if (currentId.value <= 0) {
    currentId.value = slides.length - 1
  } else {
    currentId.value -= 1
  }
}

const play = () => {
  timeId = window.setInterval(() => {
    hNextPic()
  }, duration)
}

const stopPlay = () => {
  window.clearInterval(timeId)
}

const startPlay = () => {
  play()
}

const switchToHere = (index: number) => {
  currentId.value = index
}

挂载注册定时器,卸载清除定时器

// 生命周期钩子
onMounted(() => {
  if (autoPlay) {
    play()
  }
})
onBeforeUnmount(() => {
  stopPlay()
})