<template>
<div class="slider"
@mouseup="mouseup($event)"
@mousemove="mousemove($event)"
@mousedown="mousedown($event)"
:style="{width: width + 'px', height: height + 'px'}"
>
<ul
draggable="false"
:style="{left: left + 'px', width: (data.length * width) + 'px'}"
>
<li
v-for="(item, index) in data"
:key="index"
:style="{width: width + 'px', height: height + 'px'}"
>
{{item.name}}
</li>
</ul>
<div class="slider-status">
<span v-for="(item, index) in data" :key="index" @click="statusClick(index)" :class="statusIndex == index ? 'active' : ''">{{index + 1}}</span>
</div>
</div>
</template>
<script>
export default {
data () {
return {
statusIndex: 0,
isMouseUp: false,
num: 0, // 偏移的数量
width: 600, // 容器的宽度
height: 300, // 容器的高度
left: 0, // 相对容器的偏移
startX: 0, // 鼠标按下的位置
originX: 0,
endX: 0, // 鼠标松开的位置
data: [ // 容器数据
{
id: 1,
name: 'content1'
},
{
id: 2,
name: 'content2'
},
{
id: 3,
name: 'content3'
},
{
id: 4,
name: 'content4'
}
]
};
},
computed: {
moveLeft: function () {
return this.num * this.width;
}
},
methods: {
// 鼠标点击圆点
statusClick (index) {
this.left = -index * this.width;
this.statusIndex = index;
},
// 鼠标弹开的时候触发
mouseup (event) {
this.isMouseUp = false;
this.endX = event.clientX;
let cpLeft = Math.abs(this.left);
console.log((cpLeft % 300));
console.log(Math.floor(cpLeft / 300));
// 当滑动到第一个的时候
if (Math.floor(cpLeft / this.width) == 0) {
// 鼠标向左滑动
if ((this.endX - this.startX) > 0) {
this.left = 0;
this.statusIndex = 0;
} else {
if (Math.floor(cpLeft / this.width) < (this.data.length - 1)) {
if ((cpLeft % this.width) > (this.width / 2)) {
let num = (Math.floor(cpLeft / this.width) + 1);
this.left = -(this.width * num);
this.statusIndex = num;
} else {
this.left = -(this.width * Math.floor(cpLeft / this.width));
this.statusIndex = Math.floor(cpLeft / this.width);
}
} else {
this.left = -(this.width * Math.floor(cpLeft / this.width));
this.statusIndex = Math.floor(cpLeft / this.width);
}
}
} else {
if (Math.floor(cpLeft / this.width) < (this.data.length - 1)) {
// 滑动距离大于banner的一半
if ((cpLeft % this.width) > (this.width / 2)) {
let num = (Math.floor(cpLeft / this.width) + 1); // 滑动到下一张
console.log(num + '===');
this.left = -(this.width * num);
this.statusIndex = num;
} else {
this.left = -(this.width * Math.floor(cpLeft / this.width)); // 返回到上一张
this.statusIndex = Math.floor(cpLeft / this.width);
}
} else {
this.left = -(this.width * Math.floor(cpLeft / this.width));
this.statusIndex = Math.floor(cpLeft / this.width);
}
}
},
// 鼠标按下后移动的触发
mousemove (event) {
if (this.isMouseUp) {
let moveX = event.clientX;
if (this.startX > moveX) {
this.left = this.originX - (this.startX - moveX);
} else {
this.left = this.originX + (moveX - this.startX);
}
}
},
// 鼠标按下后触发
mousedown (event) {
this.isMouseUp = true;
this.startX = event.clientX;
this.originX = this.left;
}
}
};
</script>
<style lang="less">
.slider{
position: relative;
height: 200px;
width: 300px;
margin:0 auto;
overflow: hidden;
user-select: none;
.slider-status {
width:100%;
position:absolute;
bottom:0;
height:30px;
text-align:center;
span {
display:inline-block;
height: 20px;
width:20px;
margin:0 5px;
line-height:20px;
text-align:center;
background:#ccc;
border-radius: 10px;
&.active{
background: yellow;
}
}
}
ul {
position: absolute;
width: 1200px;
transition: all .2s;
li {
float: left;
height: 200px;
width: 300px;
font-size: 40px;
color:#fff;
line-height: 200px;
text-align: center;
}
li:nth-child(1) {
background:red;
}
li:nth-child(2) {
background:pink;
}
li:nth-child(3) {
background:green;
}
li:nth-child(4) {
background:blue;
}
}
}
</style>
vue封装slider组件
于 2019-07-18 22:21:45 首次发布