效果图

竖屏移动端(vue + TS)
1.DOM
<div class="home-swiper">
<transition name="fade">
<div @touchend='end' @touchstart='start' @touchmove='move' class="swiper">
<div @click="chooseItem(item,index, config5[index])" v-for="(item, index) in imgs" :style="config5[index]"
:key="index">
<div class="swiper-box" :style="{backgroundImage: 'url('+item.cover+')'}" style="width: 100%; height: 100%;">
<p class="box-title">{{ item.label }}</p>
<p class="box-tip">{{ item.remark }}</p>
</div>
</div>
</div>
</transition>
<!--region免责声明-->
<van-dialog v-model="showDialog" class="dialog-mzsm" :showConfirmButton="false">
<div class="title">免责声明</div>
<div class="content">{{ organ.disclaimer }}</div>
<div class="btn-wrap">
<van-button type="info" plain @click="close">取消</van-button>
<van-button type="info" @click="confirm">确定</van-button>
</div>
</van-dialog>
<!--endregion-->
<!--region敬请期待-->
<van-dialog v-model="showDialogXZ" class="dialog-mzsm" :showConfirmButton="false">
<img src="../../../assets/images/home_icon.png" class="home-icon" name="home_icon"/>
<div class="xz-text">案由制作中,敬请期待</div>
<div class="btn-XZ">
<van-button type="info" @click="confirmXZ">确定</van-button>
</div>
</van-dialog>
<!--endregion-->
</div>
</template>
2.逻辑部分
<script lang="ts">
import {Vue, Component} from 'vue-property-decorator';
import {Getter, Action} from 'vuex-class';
import Organ from '@/model/Organ';
@Component({
components: {}
})
export default class HomeSwiper extends Vue {
@Action('setLitigationFeeInfo') private setLitigationFeeInfo: any;
@Action('setTop') private setTop: any;
@Getter('info')
private organ: Organ; // 机构信息
private showDialog: boolean = false; // 免责声明
private showDialogXZ: boolean = false; // 敬请期待(行政)
private currentType: string = ''; // 当前的类型
private realIndex: any;
private tag: boolean = false;
// 轮播图参数
private loading: boolean = true;
private currentIndex: number = 1; // 当前中间imgs数组中index
private startX: any = '';
private startY: any = '';
private endX: any = '';
private endY: any = '';
private imgs: any = [];
private previous: number = 0;
private config5: any = [
{
id: 'B',
position: 'absolute',
width: '39%',
height: '82%',
top: '6%',
left: '12%',
opacity: 1,
zIndex: 2,
transition: '.4s',
fontSize: '30px'
},
{
id: 'center',
position: 'absolute',
width: '45%',
height: '100%',
top: '0px',
left: '50%',
marginLeft: '-22.5%',
opacity: 1,
zIndex: 4,
transition: '.4s',
fontSize: '44px',
boxShadow: '0 0 40px 0 #3D3E45'
},
{
id: 'D',
position: 'absolute',
width: '39%',
height: '82%',
top: '6%',
left: '48.8%',
opacity: 1,
zIndex: 2,
transition: '.4s',
fontSize: '30px'
}
]; // 滑出屏幕效果样式
private timer: any; // 定时器
public created () {
this.addCardStyle(); // 加入样式位置的index
// console.log('this.organ.top:', this.organ.top);
this.imgs.length = [];
this.imgs = this.organ.top;
this.play();
}
// 自动播放
private play () {
this.timer = window.setInterval(() => {
this.prev();
// console.log('为啥要自动播放:');
}, 5000);
}
// 清除定时器
private stopPlay () {
clearInterval(this.timer);
}
// 滑动上一个
private prev () {
// this.imgs.unshift(this.imgs.pop());
this.config5.push(this.config5.shift());
this.currentIndex = this.currentIndex - 1;
if (this.currentIndex < 0) {
this.currentIndex = this.imgs.length - 1;
}
this.centerIndex('prev');
}
// 滑动下一个
private next () {
// this.imgs.push(this.imgs.shift());
this.config5.unshift(this.config5.pop());
this.currentIndex = this.currentIndex + 1;
if (this.currentIndex > this.imgs.length - 1) {
this.currentIndex = 0;
}
this.centerIndex('next');
// console.log(this.currentIndex);
}
// 开始移动端滑动屏幕
private start (event: any) {
this.startX = event.changedTouches[0].clientX;
this.startY = event.changedTouches[0].clientY;
}
// 连续滑动
private move (event: any) {
this.endY = event.changedTouches[0].clientY;
this.endX = event.changedTouches[0].clientX;
this.stopDefault(event);
}
// 滑动
private end (event: any) {
this.endY = event.changedTouches[0].clientY;
this.endX = event.changedTouches[0].clientX;
this.formatSwiper();
}
private formatSwiper () {
if (this.startX > this.endX) {
// console.log('左边滑动');
if (this.startX > this.endX + 40) {
this.next();
}
} else {
// console.log('右边滑动');
if (this.endX > this.startX + 40) {
this.prev();
}
}
}
// 阻止touchmove的横向默认事件(ios快捷操作会关闭页面)
private stopDefault (event: any) {
let differenceY = this.endY - this.startY;
let differenceX = this.endX - this.startX;
if (Math.abs(differenceX) > Math.abs(differenceY)) {
event.preventDefault();
}
}
// 当前imgs在位置上的index(并非img数组的index)
private centerIndex (val: any) {
if (val === 'prev') {
for (let val of this.imgs) {
if (val.index === this.imgs.length - 1) {
val.index = 0;
} else {
val.index = val.index + 1;
}
}
} else {
for (let val of this.imgs) {
if (val.index === 0) {
val.index = this.imgs.length - 1;
} else {
val.index = val.index - 1;
}
}
}
}
// 点击事件
private chooseItem (item: any, index: any, config: any) {
this.stopPlay(); // 关闭定时器
/*item=> top中的每一项
* index=> 索引 对应top中的id 0=》民事案 1=》行政案 2=》执行案
* config=> 当前点击项对应config5里面的样式,左=》id:B 中=》id:center 右=》id:D
* */
// console.log('config5[index]:',config);
if (config.id === 'B') { // 位置为0,右划一次,这里根据config样式中的id来判断当前点击项的左中右位置
// console.log('位置为0时左:');
this.prev();
} else if (config.id === 'D') { // 位置为2,左滑一次
// console.log('位置为2时右:');
this.next();
} else if (config.id === 'center') { // 位置在中间时,不改变
this.showDialogMZ(index);
// console.log('位置在中间');
}
}
private addCardStyle () {
if (this.imgs.length > 7) {
let addtime = this.imgs.length - 7;
for (let i = 0; i < addtime; i++) {
this.config5.push({
id: 'center',
position: 'absolute',
width: '45%',
height: '100%',
top: '0px',
left: '50%',
marginLeft: '-22.5%',
opacity: 0,
transition: '.1s'
});
}
}
}
/**
* 关闭免责声明弹窗
*/
private close () {
this.$utils.Log.saveEvent('3', '点击同意/取消', 'button');
this.showDialog = false;
}
/**
* 确认 免责声明
*/
private confirm () {
this.$utils.Log.saveEvent('3', '点击同意/取消', 'button');
this.$emit('chooseType', this.currentType); // 展示案由
this.$emit('goNext', false); // 展示案由
this.setTop(this.currentType);
}
/**
* 显示免责声明
*/
private showDialogMZ (index: number) {
let val = (this.organ.top as any).find((t: any, i: number) => index === i);
if (val.active) {
this.showDialog = true;
this.currentType = val.name;
} else {
this.showDialogXZ = true;
}
}
/**
* 确认关闭敬请期待弹窗
*/
private confirmXZ () {
this.showDialogXZ = false;
}
}
</script>
3.css
<style lang="less" scoped>
.swiper {
width: 100%;
height: 630px;
position: relative;
overflow: hidden;
.swiper-box {
background-size: 100%;
background-repeat: no-repeat;
overflow: hidden;
}
.box-title {
color: #ffffff;
line-height: 60px;
text-align: center;
margin-top: 350px;
}
.box-tip {
font-size: 30px;
color: #ffffff;
line-height: 60px;
text-align: center;
}
}
.home-icon {
width: 180px;
height: 197px;
margin: 53px 230px 0 230px;
}
.xz-text {
font-size: 36px;
color: #666666;
line-height: 55px;
text-align: center;
margin-top: 20px;
}
.btn-XZ {
text-align: center;
box-sizing: border-box;
padding-top: 50px;
height: 170px;
.van-button {
width: 135px;
height: 45px;
border: 1px solid #1989fa;
&:first-child {
margin-right: 30px;
}
}
}
</style>
修改了判断位置的方法,增加了自动播放功能(click点击时清除定时器),参考文章为展示5个卡片的示例,这里改为了3个,config样式进行了修改