轮播图之swipe实现卡片化层叠轮播图
1.安装版本
"swiper": "^4.4.2",
"vue-awesome-swiper": "^3.1.3",
2.引用
(1)当前页面
// @ts-ignore
import {swiper, swiperSlide} from 'vue-awesome-swiper';
import 'swiper/dist/css/swiper.css';
@Component({
components: {
swiper,
swiperSlide
}
})
(2)main.ts
import 'swiper/dist/css/swiper.css';
3.DOM结构
<template>
<div class="home-cover">
<swiper :options="swiperOption" ref="mySwiper" v-if="organ.top.length > 0">
<swiper-slide v-for="(t, index) in organ.top" :key="index">
<div class="ms-box swiper-item" :style="{backgroundImage: 'url('+t.bgImg+')'}">
<p class="box-title">{{ t.label }}</p>
<p class="box-tip">{{ t.remark }}</p>
</div>
</swiper-slide>
</swiper>
// 点击弹出免责声明
<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>
// 点击弹出敬请期待
<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>
</div>
</template>
organ.top
const CAUSE_TOP = [
{
id: 0,
label: '行政案风险',
name: '行政案',
bgImg: require('../../assets/images/xz_bg.png'),
remark: '当事人与政府之间行政争议',
index: 0,
cover: require('../../assets/images/xz_bg.png')
},
{
id: 1,
name: '民事案',
label: '民事案风险',
bgImg: require('../../assets/images/ms_bg.png'),
remark: '平等主体之间权利、义务纠纷',
index: 1,
cover: require('../../assets/images/ms_bg.png')
},
{
id: 2,
label: '执行案风险',
name: '执行案',
bgImg: require('../../assets/images/zx_bg.png'),
remark: '未履行生效法律文书',
index: 2,
cover: require('../../assets/images/zx_bg.png')
}
];
3.swiperOption配置参数
private swiperOption: object = { // 轮播图配置参数
speed: 300, // 自动滑动开始到结束的时间(单位ms)
loop: true, // 开启循环
centeredSlides: true, // 设定为true时,active slide会居中,而不是默认状态下的居左。
slidesPerView: 2, // 设置slider容器能够同时显示的slides数量(carousel模式)
pagination: {
el: '.swiper-pagination',
clickable: true
},
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev'
},
on: {
click: () => {
const realIndex = this.swiper.realIndex; // 点击的索引
// console.log('realIndex:', realIndex);
this.showDialogMZ(realIndex);
}
},
preventLinksPropagation: false // 阻止点击事件冒泡
};
4.css样式
/**
* @Author : XuXing
* @Date : 2019-12-25
* @Version : 1.0
* @Content : 首页(民事、行政、执行)
*/
.home-cover {
width: 1060px;
margin: 0 auto;
.ms-box {
background-size: 100%;
background-repeat: no-repeat;
overflow: hidden;
}
.swiper-slide {
height: 900px;
width: 530px !important;
.swiper-item {
margin: 100px auto;
width: 447px;
height: 530px;
border-radius: 10px;
}
}
// 前一个轮播图
.swiper-slide-prev {
margin-left: 265px;
.box-title {
font-size: 34px;
color: #ffffff;
line-height: 60px;
text-align: center;
margin-top: 300px;
}
}
// 后一个轮播图
.swiper-slide-next {
margin-left: -265px;
.box-title {
font-size: 34px;
color: #ffffff;
line-height: 60px;
text-align: center;
margin-top: 300px;
}
}
// 选中的轮播图
.swiper-slide-active{
z-index: 999;
margin-left: -265px;
.swiper-item{
width: 530px;
height: 630px;
position: relative;
top: -60px;
left: 0;
box-shadow: 0 0 40px 0 #3D3E45;
.box-title {
font-size: 44px;
color: #ffffff;
line-height: 60px;
text-align: center;
margin-top: 380px;
}
}
}
.box-title {
font-size: 34px;
color: #ffffff;
line-height: 60px;
text-align: center;
margin-top: 300px;
}
.box-tip {
font-size: 32px;
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;
}
}
}
}
源码
<!--
* @Author : XuXing
* @Date : 2019-12-25
* @Version : 1.0
* @Content : 首页(民事、行政、执行)
-->
<template>
<div class="home-cover">
<swiper :options="swiperOption" ref="mySwiper" v-if="organ.top.length > 0">
<swiper-slide v-for="(t, index) in organ.top" :key="index">
<div class="ms-box swiper-item" :style="{backgroundImage: 'url('+t.bgImg+')'}">
<p class="box-title">{{ t.label }}</p>
<p class="box-tip">{{ t.remark }}</p>
</div>
</swiper-slide>
</swiper>
<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>
<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>
</div>
</template>
<script lang="ts">
import {Vue, Component} from 'vue-property-decorator';
import {Getter, Action} from 'vuex-class';
import Organ from '@/model/Organ';
// @ts-ignore
import {swiper, swiperSlide} from 'vue-awesome-swiper';
import 'swiper/dist/css/swiper.css';
@Component({
components: {
swiper,
swiperSlide
}
})
export default class HomeCover 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;
// public swiperOption: any = {};
private swiperOption: object = { // 轮播图配置参数
speed: 300, // 自动滑动开始到结束的时间(单位ms)
loop: true, // 开启循环
centeredSlides: true, // 设定为true时,active slide会居中,而不是默认状态下的居左。
slidesPerView: 2, // 设置slider容器能够同时显示的slides数量(carousel模式)
pagination: {
el: '.swiper-pagination',
clickable: true
},
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev'
},
on: {
click: () => {
const realIndex = this.swiper.realIndex; // 点击的索引
// console.log('realIndex:', realIndex);
this.showDialogMZ(realIndex);
}
},
preventLinksPropagation: false // 阻止点击事件冒泡
};
public mounted() {
this.$nextTick(() => {
let swiper = (this.$refs.mySwiper as any).swiper;
this.swiperOption = {
speed: 300, // 自动滑动开始到结束的时间(单位ms)
loop: true, // 开启循环
centeredSlides: true, // 设定为true时,active slide会居中,而不是默认状态下的居左。
slidesPerView: 2, // 设置slider容器能够同时显示的slides数量(carousel模式)
pagination: {
el: '.swiper-pagination',
clickable: true
},
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev'
},
on: {
click: () => {
const realIndex = swiper.realIndex; // 点击的索引
// console.log('realIndex:', realIndex);
this.showDialogMZ(realIndex);
}
},
preventLinksPropagation: false // 阻止点击事件冒泡
};
this.$forceUpdate();
});
}
private get swiper () {
return (this.$refs.mySwiper as any).swiper;
}
/**
* 关闭免责声明弹窗
*/
private close () {
this.$utils.Log.saveEvent('3', '点击同意/取消', 'button');
this.showDialog = false;
}
/**
* 确认 免责声明
*/
private confirm () {
// this.$store.commit('SET_CURR_CAUSE', this.selectId);
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>
<style lang="less">
@import "index";
</style>
坑1
点击事件不能绑在DOM结构上,必须写在配置参数里,通过计算属性获取实例绑定,为啥呢?因为绑定在DOM上后,向前滑动时点击事件不生效
private get swiper () {
return (this.$refs.mySwiper as any).swiper;
}
坑2
注意swipe版本不同、参数写法不同,并且引用不了!
坑3
最后坑全填平之后,关键问题来了,滑动极度卡顿,轮播的内容显示不全,所以废了,以上内容全部废弃,啊,我死了!但是我倔强地复制留着了
填坑时参考的文章
点击事件的问题www.cnblogs.com/tangbuluo/p…
点击事件的问题segmentfault.com/a/119000001…
点击事件的问题blog.csdn.net/gaoqiang111…