最近项目中做了一个轮播图,类似于下图腾讯云首页这种。不想用现成的组件,所以自己写了把它抽成了组件
先上代码:
html部分
写成这样是考虑每一个banner的结构是不一样的,一样的话可以写成v-for更优雅(图片的动态引用需要加require)
<div class="banner">
<ul ref="titleboxList" class="banner__list" @mouseover="bannerStop" @mouseleave="bannerStart">
<li class="banner__item" :class="titleListIndex === 1 ? 'check' : 'uncheck'">
<div class="banner__item-1">
<div class="left">
<span class="left-hd">banner1</span>
<span class="left-btn1">了解更多</span>
<div>
<span class="left-btn2">立即咨询</span>
<span class="left-btn3">解决方案手册</span>
<span class="left-btn4">立即试用</span>
</div>
</div>
<div class="right"><img src="titleItem1.png" alt="" /></div>
</div>
</li>
<li class="banner__item" :class="titleListIndex === 2 ? 'check' : 'uncheck'">
<div class="banner__item-1">
<div class="left">
<span class="left-hd">banner2</span>
<span class="left-btn1">了解更多</span>
<div>
<span class="left-btn2">立即咨询</span>
<span class="left-btn3">解决方案手册</span>
<span class="left-btn4">立即试用</span>
</div>
</div>
<div class="right"><img src="titleItem1.png" alt="" /></div>
</div>
</li>
<li class="banner__item" :class="titleListIndex === 3 ? 'check' : 'uncheck'">
<div class="banner__item-1">
<div class="left">
<span class="left-hd">banner3</span>
<span class="left-btn1">了解更多</span>
<div>
<span class="left-btn2">立即咨询</span>
<span class="left-btn3">解决方案手册</span>
<span class="left-btn4">立即试用</span>
</div>
</div>
<div class="right"><img src="titleItem1.png" alt="" /></div>
</div>
</li>
<li class="banner__item" :class="titleListIndex === 4 ? 'check' : 'uncheck'">
<div class="banner__item-1">
<div class="left">
<span class="left-hd">banner4</span>
<span class="left-btn1">了解更多</span>
<div>
<span class="left-btn2">立即咨询</span>
<span class="left-btn3">解决方案手册</span>
<span class="left-btn4">立即试用</span>
</div>
</div>
<div class="right"><img src="titleItem1.png" alt="" /></div>
</div>
</li>
</ul>
<div class="banner__ctrl">
<ul @mouseover="bannerStop" @mouseleave="bannerStart">
<li class="banner__ctrl-item" @click="titleListIndex = 1">
<a :class="titleListIndex === 1 ? 'check' : ''"></a>
</li>
<li class="banner__ctrl-item" @click="titleListIndex = 2">
<a :class="titleListIndex === 2 ? 'check' : ''"></a>
</li>
<li class="banner__ctrl-item" @click="titleListIndex = 3">
<a :class="titleListIndex === 3 ? 'check' : ''"></a>
</li>
<li class="banner__ctrl-item" @click="titleListIndex = 4">
<a :class="titleListIndex === 4 ? 'check' : ''"></a>
</li>
</ul>
</div>
</div>
样式部分css
用了scss
.banner {
&__list {
width: 1200px;
height: 427px;
}
&__ctrl {
position: absolute;
top: 300px;
width: 100%;
&-item {
display: inline-block;
width: 26px;
height: 25px;
margin: 0 4px;
cursor: pointer;
a {
display: inline-block;
width: 26px;
height: 5px;
background: #35465a;
border-radius: 3px;
}
}
.check {
background: #5375ff;
}
}
&__item {
position: absolute;
@mixin afterMixin {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
height: 420px;
content: '';
opacity: 0.1;
}
@mixin btnMixin {
display: block;
padding: 0 3px;
height: 32px;
margin-top: 20px;
font-size: 14px;
font-weight: 500;
line-height: 32px;
border-radius: 2px;
}
&-1::after {
@include afterMixin;
background: url(titleboxback.png);
}
&-1 {
width: 1200px;
height: 427px;
.left {
position: absolute;
top: 106px;
left: 130px;
z-index: 100;
display: flex;
flex-direction: column;
&-hd {
font-size: 34px;
font-weight: 500;
line-height: 48px;
color: #87cbff;
text-align: left;
}
&-btn1 {
@include btnMixin;
color: #e8e8e8;
border: 1px solid #e8e8e8;
}
&-btn2 {
@include btnMixin;
color: #fff;
background: #1677ff;
}
&-btn3 {
@include btnMixin;
background: #fff;
}
&-btn4 {
@include btnMixin;
color: #fff;
background: #ff6010;
}
span {
cursor: pointer;
}
}
.right {
position: absolute;
top: 88px;
right: 0;
}
}
&-2::after {
@include afterMixin;
background-color: red;
}
&-3::after {
@include afterMixin;
background-color: yellow;
}
&-4::after {
@include afterMixin;
background-color: green;
}
.check {
opacity: 1 !important;
}
}
.check {
animation: showtip 0.7s 1;
animation-fill-mode: forwards;
}
.uncheck {
animation: hidetip 0.5s 1;
animation-fill-mode: forwards;
}
@keyframes showtip {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes hidetip {
0% {
opacity: 1;
}
100% {
display: none;
opacity: 0;
}
}
}
js逻辑部分
export default {
name: 'TitleBanner',
data() {
return {
titleListIndex: 1,
bannerInterval: null //轮播计时事件
}
},
mounted() {
this.bannerStart()
},
beforeDestroy() {
this.bannerStop()
},
methods: {
bannerStart() {
let self = this
if (this.bannerInterval != null) {
this.bannerStop()
}
this.bannerInterval = window.setInterval(self.bannerOvers, 4000)
},
bannerStop() {
window.clearInterval(this.bannerInterval)
this.bannerInterval = null
},
bannerOvers() {
let titleboxListArr = Array.from(this.$refs.titleboxList.children)
if (this.titleListIndex === titleboxListArr.length) {
this.titleListIndex = 1
} else {
this.titleListIndex = this.titleListIndex + 1
}
}
}
}
思路
说一下大致的思路,页面开始执行setInterval,鼠标滑入时终止setInterval事件,我在这里的banner__ctrl部分因为设置了最上层,所以这个也要单独加划入划出事件。渐进渐出的效果用的是动画实现,比较简单,不过记得在消失时要设置display: none。 也没看什么攻略,全是自己想着写的,设计简单,有什么建议个批评都可以指正。