纯 CSS,Vue,React 实现轮播图, 帮你全部搞定
之前我们写了一篇使用 CSS 实现的
现在我们用 React 框架来实现一波。
React
最开始传入图片数据
import Banner from './banner'
let imgUrl = [
'https://img.zcool.cn/community/010c815e25a8c4a801216518dcc1d4.jpg@1280w_1l_2o_100sh.jpg', 'https://img.zcool.cn/community/0189905e25a8c6a80120a89533cc7f.jpg@1280w_1l_2o_100sh.jpg', 'https://img.zcool.cn/community/01747f5e25a8c9a801216518193452.jpg@1280w_1l_2o_100sh.jpg', 'https://img.zcool.cn/community/01cbba5e25a8cea80120a895743281.jpg@1280w_1l_2o_100sh.jpg', 'https://img.zcool.cn/community/0186025e25a8d3a80121651827af9c.jpg@1280w_1l_2o_100sh.jpg'
]
function App() {
return (
<div>
<Banner
imgUrl={imgUrl}
/>
</div>
);
}
export default App;
基础架构:中间展示图片,两边箭头,下面依据图片数量生成的小圆点
import React from "react"
import "./banner.css"
export default class Banner extends React.Component {
render() {
return (
<div
className="container"
>
<div className="swiper-box">
{
this.props.imgUrl.map((item, index) => {
return (
<div className="swiper-item" key={index}>
<img src={item} alt="" />
</div>
)
})
}
</div>
<div className="swiper-arrow">
<div className="arrowLeft iconfont iconqianjin1"></div>
<div className="arrowRight iconfont iconqianjin"></div>
</div>
<div className="focus">
{
this.props.imgUrl.map((item, index) => {
return (
<div></div>
)
})
}
</div>
</div>
)
}
}
咦咦咦咦~~~~,so ugly
为实现无缝衔接轮播,我们需要重新去生成一份数组。props
中解构出 imgUrl
。
constructor(props) {
super(props)
let { imgUrl } = this.props
let imgUrlClone = []
imgUrlClone = imgUrlClone.concat([], imgUrl)
imgUrlClone.push(imgUrl[0])
imgUrlClone.unshift(imgUrl[imgUrl.length - 1])
console.log(imgUrlClone)
}
一顿操作下来,假设 imgUrl = [A, B, C, D, E]
=> imgUrlClone = [E, A, B, C, D, E, A]
{
this.imgUrlClone.map((item, index) => {
return (
<div className="swiper-item" key={index}>
<img src={item} alt="" />
</div>
)
})
}
接下来,要将图片的显示变为正常样式
let { width, height, step, speed } = this.state;
let swiperBoxStyle = {
width: `${this.imgUrlClone.length * width}px`,
left: `${-step * width}px`,
height: height + "px",
transition: `all ${speed}ms linear`
}
let commom = {
width: width + "px",
height: height + "px"
}
分别加到 className="container"
和 className="swiper-box"
上。
静态布局结束之后,让我们的图片动起来。
this.state = { speed, step, width, height }
componentDidMount() {
if (this.props.autoplay) {
this.timer = setInterval(() => {
this.next()
}, this.props.interval);
}
}
next = () => {
let { step } = this.state
if (step >= this.imgUrlClone.length - 1) {
this.setState({
step: 1,
speed: 0
})
}
setTimeout(() => {
this.setState({
step: this.state.step + 1,
speed: this.props.speed
})
}, 0)
}
切换小圆点对应的 active
样式
<div className="focus">
{
this.props.imgUrl.map((item, index) => {
if (step === this.imgUrlClone.length - 1) {
step = 1
}
if (step === 0) {
step = this.imgUrlClone.length - 2
}
return (
<div className={index + 1 === step ? "active" : ""} key={index}></div>
)
})
}
</div>
为左右箭头添加事件
<div className="swiper-arrow">
<div className="arrowLeft iconfont iconqianjin1" onClick={this.prev}></div>
<div className="arrowRight iconfont iconqianjin" onClick={this.next}></div>
</div>
prev = () => {
let { step } = this.state
if (step <= 0) {
this.setState({
step: this.imgUrlClone.length - 2,
speed: 0
})
}
setTimeout(() => {
this.setState({
step: this.state.step - 1,
speed: this.props.speed
})
}, 0)
}
锦上添花,鼠标移入,轮播停止。鼠标移出,轮播继续
<div
className="container"
style={commom}
onMouseEnter={this.removeInte}
onMouseLeave={this.addInter}
></div>
removeInte = () => {
clearInterval(this.timer)
}
addInter = () => {
if (!this.props.autoplay) return
this.timer = setInterval(() => {
this.next()
}, this.props.interval);
}
转载自:https://juejin.cn/post/7114573566061854751