實(shí)現(xiàn)的基本功能:
- 自動(dòng)播放,暴露自動(dòng)輪播的屬性,設(shè)置了自動(dòng)輪播。
- 如果有自動(dòng)播放,鼠標(biāo)進(jìn)入,自動(dòng)播放停止,暫停自動(dòng)播放開啟。
- 指示器切換,鼠標(biāo)可點(diǎn)擊上一頁和下一頁。
步驟:
- 實(shí)現(xiàn)通用組件輪播圖樣式的基本布局
- 設(shè)置為局部組件
- 設(shè)置業(yè)務(wù)組件
- 將業(yè)務(wù)組件導(dǎo)入到項(xiàng)目中
(1) 在src/libs/Carousel.vue(這是輪播圖的通用組件基本構(gòu)建)
<template>
<div class="xtx-carousel">
<ul class="carousel-body fade">
<li
class="carousel-item"
>
<router-link to="/doc/carousel"
><img src="圖片地址" alt=""
/></router-link>
</li>
</ul>
<a href="javascript:;" class="carousel-btn pre" >
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-zuojiantou"></use></svg
></a>
<a href="javascript:;" class="carousel-btn next">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-youjiantou"></use></svg
></a>
<div class="carousel-indictor">
<span
v-for="i in sliders.length"
:key="i"
></span>
</div>
</div>
</template>
<script lang="ts">
</script>
<style lang="scss" scoped>
.xtx-carousel {
position: relative;
width: 100%;
height: 100%;
.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%;
}
}
&-indictor {
position: absolute;
left: 0;
bottom: 0px;
z-index: 2;
@media (max-width: 500px) {
width: 100%;
}
width: 750px;
text-align: center;
span {
display: inline-block;
width: 12px;
height: 12px;
background: rgba(0, 0, 0, 0.4);
border-radius: 50%;
cursor: pointer;
~ span {
// span中的每個(gè)span
margin-left: 12px;
}
&.active {
background: #fff;
}
}
}
&-btn {
width: 44px;
height: 44px;
color: #fff;
background: rgba(0, 0, 0, 0.2);
border-radius: 50%;
position: absolute;
top: 228px;
z-index: 2;
text-align: center;
line-height: 44px;
opacity: 0;
transition: all 0.5s;
@media (max-width: 500px) {
top: 110px;
}
&.pre {
left: 20px;
@media (max-width: 500px) {
left: 10px;
}
}
&.next {
right: 20px;
@media (max-width: 500px) {
right: 10px;
}
}
}
&:hover {
.carousel-btn {
opacity: 1;
}
}
}
&:hover {
.carousel-btn {
opacity: 1;
}
}
}
</style>
(2) 構(gòu)建首頁輪播圖的業(yè)務(wù)組件的基本布局。
src/component/CarouselDemo.vue
<template>
<div class="home-banner">
//輪播圖imgUrl的數(shù)組,然后傳給通用組件的輪播圖,速度為2s,啟動(dòng)自動(dòng)播放
<Carousel :sliders="sliders" :duration="2" :autoplay="true"></Carousel>
</div>
</template>
<script lang="ts">
import Button from "../libs/Button.vue";
import Carousel from "../libs/Carousel.vue"; //引入文件夾中的圖片
import imgUrl1 from "../assets/1.jpg";
import imgUrl2 from "../assets/2.jpg";
import imgUrl3 from "../assets/3.jpg";
import imgUrl4 from "../assets/4.jpg";
import imgUrl5 from "../assets/5.jpg";
import { reactive } from "vue";
export default {
components: { Carousel },
setup(props) {
const sliders = reactive([
{ imgUrl: imgUrl1 },
{ imgUrl: imgUrl2 },
{ imgUrl: imgUrl3 },
{ imgUrl: imgUrl4 },
{ imgUrl: imgUrl5 },
]);
return { sliders }; //得到輪播圖imgUrl的數(shù)組,然后傳給通用組件輪播圖
},
};
</script>
<style lang="scss">
.home-banner {
width: 750px;
height: 500px;
}
@media (max-width: 500px) {
.home-banner {
width: 100%;
height: 241px;
}
}
</style>
(3) 實(shí)現(xiàn)功能以寫入如下代碼中
全部代碼:
<template>
<div class="xtx-carousel">
<ul class="carousel-body">
<li
class="carousel-item"
v-for="(item, i) in sliders"
:key="item.i"
:class="{ fade: index === i }"
@mouseenter="stop"
@mouseleave="start"
>
<router-link to="/doc/carousel"
><img :src="item.imgUrl" alt=""
/></router-link>
<a href="javascript:;" class="carousel-btn pre" @click="toggle(-1)">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-zuojiantou"></use></svg
></a>
<a href="javascript:;" class="carousel-btn next" @click="toggle(1)">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-youjiantou"></use></svg
></a>
<div class="carousel-indictor">
<span
v-for="i in sliders.length"
:key="i"
:class="{ active: index === i - 1 }"
></span>
</div>
</li>
</ul>
</div>
</template>
<script lang="ts">
import { onMounted, ref, watch } from "vue";
export default {
props: {
sliders: {
type: Array,
default: () => [],
},
duration: {
type: Number,
default: 2,
},
autoplay: {
type: Boolean,
default: true,
},
},
setup(props) {
console.log(props.sliders);
// 自動(dòng)輪播的效果
const index = ref(0); //index初始值為0模板可以現(xiàn)實(shí)第一張圖
let timer = null;
const autoplayFn = () => {
clearInterval(timer);
//自動(dòng)輪播
timer = setInterval(() => {
index.value++;
if (index.value >= props.sliders.length) {
index.value = 0;
}
}, props.duration * 1000); //設(shè)置為秒
};
watch(
() => props.sliders,
() => {
if (props.autoplay && props.sliders.length > 0) {
autoplayFn();
}
},
{
immediate: true,
}
);
// 1.左右箭頭點(diǎn)擊顯示上一頁或者下一頁
const toggle = (step) => {
index.value += step;
// 點(diǎn)擊右鍵
if (index.value >= props.sliders.length) {
index.value = 0;
return;
}
// 點(diǎn)擊左鍵
if (index.value < 0) {
index.value = props.sliders.length - 1;
}
};
// 2.進(jìn)入輪播圖就停止,離開就繼續(xù)輪播
const start = () => {
if (props.sliders.length > 0 && props.autoplay) {
autoplayFn();
}
};
const stop = () => {
clearInterval(timer);
};
// 最后銷毀定時(shí)器,不然已經(jīng)看不到輪播圖了,一致還在浪費(fèi)資源
// onMounted(() => {
// clearInterval(timer);
// });
return { index, start, toggle, stop };
},
};
</script>
<style lang="scss" scoped>
.xtx-carousel {
position: relative;
width: 100%;
height: 100%;
.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%;
}
}
&-indictor {
position: absolute;
left: 0;
bottom: 0px;
z-index: 2;
@media (max-width: 500px) {
width: 100%;
}
width: 750px;
text-align: center;
span {
display: inline-block;
width: 12px;
height: 12px;
background: rgba(0, 0, 0, 0.4);
border-radius: 50%;
cursor: pointer;
~ span {
// span中的每個(gè)span
margin-left: 12px;
}
&.active {
background: #fff;
}
}
}
&-btn {
width: 44px;
height: 44px;
color: #fff;
background: rgba(0, 0, 0, 0.2);
border-radius: 50%;
position: absolute;
top: 228px;
z-index: 2;
text-align: center;
line-height: 44px;
opacity: 0;
transition: all 0.5s;
@media (max-width: 500px) {
top: 110px;
}
&.pre {
left: 20px;
@media (max-width: 500px) {
left: 10px;
}
}
&.next {
right: 20px;
@media (max-width: 500px) {
right: 10px;
}
}
}
&:hover {
.carousel-btn {
opacity: 1;
}
}
}
&:hover {
.carousel-btn {
opacity: 1;
}
}
}
</style>