效果图
类似于https://location.seeklane.com/szw/prod2/index.html#/location/home
滑动居中切换是swiper自带的
swiper也有点击居中的方法
也可以自己手写一个
代码:
<template>
<div class="divide-bar">
<div v-if="this.maps.length > 1">
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide"
:class="`${mapIdTemp==index ? 'swiper-slide-duplicate-active' : ''}`"
v-for="(item,index) in this.maps"
:key="index"
@click="select(index, $event)">{{item.alias}}</div>
</div>
</div>
</div>
<div v-else
class="divide-bar-stage">
<div class="divide-bar-container">
<div class="divide-bar-item single active">this.maps[0].alias</div>
</div>
</div>
</div>
</template>
<script>
import $ from "jquery";
import Swiper from "swiper"; //导入
import { mapGetters, mapActions } from "vuex";
export default {
name: "DivideBar",
props: {
showMutilBar: {
type: Boolean,
default: !0,
},
},
data () {
return {
stageHeigth: 90,
itemHeight: 25,
rotateRate: 0,
itemNum: 0,
zDistance: 0,
realRotate: 0,
lastRotate: 0,
eachOffset: 0,
touchStart: 0,
moveDistance: 0,
isTouch: !1,
mapIdTemp: 0,
position: '',
marginTop:40
};
},
//Y.c mapGetters
//Y.d mapMutations commit
//Y.b mapActions dispatch
computed: {
...mapGetters({
maps: "maps",
mapId: "mapId",
}),
},
watch: {
maps (t) {
// this.init();
},
mapId (t) {
// this.select(t);
},
},
mounted () {
this.showMutilBar && $(".divide-bar").prepend(window.mutilBar);
this.init();
let self = this;
// 方法一:
var mySwiper = new Swiper('.swiper-container', {
direction: 'vertical',
slideToClickedSlide: true,
centeredSlides: true,
slidesPerView: 3.5, // 设置slider容器能够同时显示的slides数量
on: {
slideChange: function (e) {
self.select(this.activeIndex, e);
}
}
})
mySwiper.setTranslate(0)
// 方法二:
let mySwiper = new Swiper(".swiper-container", {
direction: 'vertical',
slidesPerView: 'auto',
observeParents: true,
centeredSlides: true, //设定为true时,active slide会居中,而不是默认状态下的居左。
on: {
slideChange: function (e) {
// this执行swiper
this.position = self.itemHeight * e.el.offsetTop;
self.select(this.activeIndex, e);
},
click: function (e) {
self.position = self.itemHeight * e.clickedIndex;
self.swiperHeight = mySwiper.$el[0].offsetHeight
self.maxTranslate = mySwiper.maxTranslate();
self.maxHeight = -self.maxTranslate + self.swiperHeight / 2
let slide, slideTop, slideHeight, slideCenter, nowTlanslate;
slideTop = self.position;
slideHeight = self.itemHeight;
slideCenter = slideTop + slideHeight / 2;
if (slideCenter <= self.swiperHeight / 2){
if (slideCenter === 12.5)
{
mySwiper.setTransition(300)
mySwiper.setTranslate(self.itemHeight + self.marginTop)
} else if (slideCenter === 37.5)
{
mySwiper.setTransition(300)
mySwiper.setTranslate(0+self.marginTop)
}
} else if (slideCenter >= self.maxHeight){
if (slideCenter === 62.5)
{
mySwiper.setTransition(300)
mySwiper.setTranslate(-self.itemHeight + self.marginTop)
} else
{
mySwiper.setTransition(300)
mySwiper.setTranslate(-50+self.marginTop)
}
} else
{
if (slideCenter === 62.5)
{
mySwiper.setTransition(300)
mySwiper.setTranslate(-self.itemHeight + self.marginTop)
} else
{
mySwiper.setTransition(300)
mySwiper.setTranslate(-50 + self.marginTop)
}
}
}
}
})
},
methods: {
init () {
this.store;
this.itemNum = this.maps.length + 5;
this.rotateRate = 360 / this.itemNum;
this.zDistance =
this.itemHeight / (2 * Math.tan((this.rotateRate / 360) * Math.PI));
this.updateMapId(this.mapId);
},
select (t, e) {
// this.mapIdTemp = t
if (e.path)
{
this.position = e.path[0].offsetTop;
} else
{
this.position = e.el.offsetTop
}
this.updateMapId(t);
},
updateMapId (t) {
t > this.maps.length - 1 || t < 0
? console.log("mapid错误" + t)
: (t !== this.mapIdTemp &&
((this.realRotate = -this.rotateRate * t), (this.mapIdTemp = t)),
t !== this.mapId && this.setMapId(t));
}
},
};
</script>
<style lang="scss" scoped>
.divide-bar {
visibility: visible;
}
.swiper-wrapper {
// margin-top: 0.2rem;
}
.swiper-container {
width: 100%;
height: 100%;
overflow: visible !important;
margin-top: -40px;
}
.swiper-slide {
width: 0.66667rem;
height: 0.66667rem !important;
line-height: 0.66667rem;
font-size: 0.34333rem;
margin-bottom: 0px !important;
transition: 300ms;
// transform: scale(0.8);
}
.swiper-slide-active,
.swiper-slide-duplicate-active {
background: #00bc92;
border-radius: 50%;
color: #ffffff;
font-size: 0.38667rem;
transform: scale(1);
}
</style>
当用力上下滑动时,最后一个和第一个都希望在中间