过程
查看完整代码直接跳到结尾git链接🔗。
1.项目结构
2.设计组件
2.1 swiper设计
<template>
<!--id,class用来设计样式;因为我不是很熟悉,所以不做说明。-->
<div id="r-swiper">
<div class="swiper"
@touchstart="touchStart"
@touchend="touchEnd"> <!--用来获取点击事件-->
<slot name="picslot"></slot>
</div>
</div>
<!--之所以平级设计是因为小圆点之后position:absolute是相对于父组件的位置,
因此想要固定在最上方就要评级设计是的相对id='app'固定-->
<div class="indicator">
<div
v-for="index in swiperItemCount"
:key="index"
class="indicator-item"
:class="{active: index === currentIndex+1}"
></div><!--动态绑定,用来显示小圆点-->
</div>
</template>
2.2 swiper-item设计
<template>
<!-- 子组件插入图片 -->
<div class="r-swiper-item">
<slot></slot>
</div>
</template>
3.设计样式
3.1 App.vue
<style>
#app {
overflow: hidden;
position: relative;
}
</style>
3.2 swiper
<style scoped>
/* #r-swiper {
overflow: hidden;
position: relative;
} */
.swiper {
display: flex;
}
.indicator {
display: flex;
/* 子元素水平居中 */
justify-content: center;
/* 相对父元素绝对位置,抽离出显示流 */
position: absolute;
width: 100%;
bottom: 10px;
}
.indicator-item {
/* 为元素指定的任何内边距和边框
都将在已设定的宽度和高度内进行绘制 */
box-sizing: border-box;
width: 8px;
height: 8px;
border-radius: 4px;
background-color: rgb(122, 122, 122);
margin: 8px;
line-height: 8px;
}
.active {
background-color: rgba(212, 62, 46, 1);
}
</style>
3.3 swiper-item
<style scoped>
.r-swiper-item {
width: 100%;
/* 等比例缩小个元素,为0则不进行缩放。
但是上面的属性依然生效。 */
flex-shrink: 0;
}
.r-swiper-item img{
width: 100%;
}
</style>
4.设计响应事件(较困难涉及js知识)
4.1 App
<script>
export default {
name: "app",
components: {
swiper,
swiperItem,
},
data() {
return {
list: [
{
src: require("./assets/pic/001.jpg"),
alt: 'first-picture.'
},
{
src: require("./assets/pic/003.jpg"),
},
{
src: require("./assets/pic/006.jpg"),
},
{
src: require("./assets/pic/007.jpg"),
},
],
current:0,
};
},
methods:{
transitionEnd(currentIndex){
if(typeof currentIndex === 'number'){
this.current = currentIndex;
}
}
}
};
import swiper from "./components/swiper";
import swiperItem from "./components/swiper-item";
</script>
4.2 swiper
<script>
export default {
name: "swiper",
props: {
interval: {
type: Number,
default: 3000,
},
},
data() {
return {
swiperItemCount: 0,
currentIndex: 0,
swiperStyle: {},
totalWidth: 0,
scrolling: false,
};
},
mounted: function () {
setTimeout(() => {
this.handleDOM();
this.startTimer();
}, 200);
},
methods: {
handleDOM() {
// 找到要操作的元素,swiper和swiperItem
let swiperElement = document.querySelector("#r-swiper");
let swiperItemElements = swiperElement.getElementsByClassName(
"r-swiper-item"
);
this.swiperItemCount = swiperItemElements.length;
this.swiperStyle = swiperElement.style;
this.totalWidth = swiperElement.offsetWidth;
},
startTimer() {
this.playTimer = window.setInterval(() => {
this.currentIndex++;
if (this.currentIndex >= this.swiperItemCount) {
this.currentIndex = this.currentIndex % this.swiperItemCount;
}
this.$emit("transitionEnd", this.currentIndex);
this.scrollContent(-this.currentIndex * this.totalWidth);
}, this.interval);
console.log("startTimer:" + this.startTimer);
},
stopTimer(){
window.clearInterval(this.playTimer);
},
scrollContent(movedis) {
this.scrolling = true;
this.swiperStyle.transition = `transform 1000ms`;
this.setTransform(movedis);
this.scrolling = false;
},
setTransform(movedis) {
// 设置滚动位置
this.swiperStyle.transform = `translate3d(${movedis}px,0,0)`;
this.swiperStyle["-webkit-transform"] = `translate3d(${movedis}px, 0, 0)`;
this.swiperStyle["-ms-transform"] = `translate3d(${movedis}px, 0, 0)`;
},
/**
* 处理滑动事件
*/
touchStart:function(event){
// 滚动过程中不能拖动,结束此函数。
if(this.scrolling) return;
// 停止定时器。
this.stopTimer();
// 保存开始滚动的位置
this.startX = event.targetTouches[0].clientX;
},
touchEnd(e){
this.endX = e.changedTouches[0].clientX;
let currentMove = this.endX - this.startX;
this.checkPosition(currentMove);
this.scrollContent(-this.currentIndex * this.totalWidth);
this.startTimer();
},
checkPosition(currentMove){
if(Math.abs(currentMove) > 0.3*this.totalWidth){
if(currentMove > 0) {
if(this.currentIndex > 0){
this.currentIndex--;
}else {
this.currentIndex = this.swiperItemCount-1;
}
}else if(currentMove < 0) {
if(this.currentIndex<this.swiperItemCount-1){
this.currentIndex++;
}else {
this.currentIndex = 0;
}
} else {
}
}
}
},
};
</script>
4.3 swiper-item
<script>
export default {
name: 'swiperitem',
}
</script>
5.运行效果
参考链接:https://github.com/coderwhy/supermall.git
庄周晓梦迷蝴蝶,望帝春心托杜鹃。——李商隐