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 timersLanding 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