286 lines
7.5 KiB
Vue
286 lines
7.5 KiB
Vue
<template>
|
||
<view :style="{height: height+'rpx'}" style="overflow: hidden;">
|
||
<esc-swiper :mode="mode" v-if="normalList.length" :autoplay="autoplay" :scale="1.1666" :circular="circular"
|
||
:current.sync="current" :size="normalList.length" :plus="plus" :width="width" :height="height"
|
||
:itemWidth="itemWidth" :itemHeight="itemHeight" :space="space" :interval="interval">
|
||
<esc-swiper-item @click="itemClick(item)" v-for="(item, idx) in normalList" :index="idx" :key="idx">
|
||
<esc-bg-view :src="item.cover" :width="itemWidth" :height="itemHeight">
|
||
<view v-if="dotMode === 'nav'" key="nav" :style="{
|
||
bottom: '0',
|
||
width:itemWidth + 'rpx'
|
||
}" class="uni-swiper__dots-box uni-swiper__dots-nav flex-row">
|
||
<text :style="{ color: dots.color }" class="flex-1 uni-swiper__dots-nav-item">{{
|
||
item[field]
|
||
}}</text>
|
||
</view>
|
||
</esc-bg-view>
|
||
</esc-swiper-item>
|
||
<!-- <template slot="dot">
|
||
<view v-if="dotMode === 'default' || dotMode === 'nav'"
|
||
:style="{ bottom: dots.bottom + 'px', 'justify-content': dotMode === 'nav' ? 'right' : 'center', right: dotMode === 'nav' ? '50rpx' : 0, 'flex-direction': dotMode === 'nav' ? 'row-reverse' : 'row' }"
|
||
class="uni-swiper__dots-box" key="default">
|
||
<view v-for="(item, index) in swiperList" @click="clickItem(index)"
|
||
:class="[index === current && 'uni-swiper__dots-bar']" :style="{
|
||
width: (index === current ? dots.width * 3 : dots.width) + 'rpx',
|
||
height: dots.height + 'rpx',
|
||
'background-color':
|
||
index !== current
|
||
? dots.backgroundColor
|
||
: dots.selectedBackgroundColor,
|
||
border: index !== current ? dots.border : dots.selectedBorder,
|
||
}" :key="index" class="uni-swiper__dots-item" />
|
||
</view>
|
||
<view v-else-if="dotMode === 'dot'" :style="{ bottom: dots.bottom + 'px' }" class="uni-swiper__dots-box"
|
||
key="dot">
|
||
<view v-for="(item, index) in swiperList" @click="clickItem(index)" :style="{
|
||
width: dots.width + 'rpx',
|
||
height: dots.height + 'rpx',
|
||
'background-color':
|
||
index !== current
|
||
? dots.backgroundColor
|
||
: dots.selectedBackgroundColor,
|
||
border: index !== current ? dots.border : dots.selectedBorder
|
||
}" :key="index" class="uni-swiper__dots-item" />
|
||
</view>
|
||
|
||
</template> -->
|
||
</esc-swiper>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import { getSwiperList } from '@/components/sn-swiper/esc-swiper/helper.js';
|
||
export default {
|
||
// * @description 自定义swiper (不支持使用class)
|
||
// * @property {String} mode = [normal|3d] 模式
|
||
// * @property {Number} width 宽
|
||
// * @property {Number} height 高
|
||
// * @property {Number} itemWidth 项宽
|
||
// * @property {Number} itemHeight 项高
|
||
// * @property {Number} space 间距
|
||
// * @property {Number} plus 左右追加个数(开启循环必填,至少为2)
|
||
// * @property {Boolean} autoplay 自动轮播
|
||
// * @property {Boolean} circular 是否循环,如果开启,至少需要3项
|
||
// * @property {String} mode = [default|dot|nav|] 指示点的类型
|
||
// * @value round 圆形指示点
|
||
// * @value round 指示点
|
||
// * @value dot 条形指示点
|
||
// * @property {String} field mode 为 nav 时,显示的内容字段(mode = nav 时必填)
|
||
// * @property {String} swiperList 轮播图的数据,通过数组长度决定指示点个数
|
||
// * @property {Object} dotsStyles 指示点样式
|
||
// * @value width 宽
|
||
// * @value height 高
|
||
// * @value bottom 离底部距离
|
||
// * @value color 文字颜色
|
||
// * @value backgroundColor 背景颜色
|
||
// * @value border 边框
|
||
// * @value selectedBackgroundColor 高亮背景
|
||
// * @value selectedBorder 高亮边框
|
||
// * @property {function} itemClick 点击事件
|
||
|
||
props: {
|
||
mode: {
|
||
type: String,
|
||
default: '3d'
|
||
},
|
||
width: {
|
||
type: Number,
|
||
default: () => 680
|
||
},
|
||
height: {
|
||
type: Number,
|
||
default: () => 550
|
||
},
|
||
itemWidth: {
|
||
type: Number,
|
||
default: () => 326
|
||
},
|
||
itemHeight: {
|
||
type: Number,
|
||
default: () => 452
|
||
},
|
||
space: {
|
||
type: Number,
|
||
default: () => 40
|
||
},
|
||
plus: {
|
||
type: Number,
|
||
default: () => 0
|
||
},
|
||
autoplay: {
|
||
type: Boolean,
|
||
default: () => true
|
||
},
|
||
// 是否循环,如果开启,至少需要3项
|
||
circular: {
|
||
type: Boolean,
|
||
default: () => false
|
||
},
|
||
swiperList: {
|
||
type: Array,
|
||
default: () => []
|
||
},
|
||
// 是否卡片
|
||
isCard: {
|
||
type: Boolean,
|
||
default: () => true
|
||
},
|
||
// 类型 :default(默认)
|
||
dotMode: {
|
||
type: String,
|
||
default: () => 'dot'
|
||
},
|
||
dotsStyles: {
|
||
type: Object,
|
||
default: () => { }
|
||
},
|
||
// 只在dotMode nav 模式下生效,变量名称
|
||
field: {
|
||
type: String,
|
||
default: 'title'
|
||
},
|
||
interval: {
|
||
type: Number,
|
||
default: () => 3000
|
||
}
|
||
},
|
||
|
||
data() {
|
||
return {
|
||
current: 0,
|
||
dots: {
|
||
width: 10,
|
||
height: 10,
|
||
bottom: 10,
|
||
color: '#FFFFFF',
|
||
backgroundColor: '#FFFFFF',
|
||
border: 'none',
|
||
selectedBackgroundColor: '#c59f71',
|
||
selectedBorder: '1px #c59f71 solid'
|
||
}
|
||
};
|
||
},
|
||
computed: {
|
||
normalList() {
|
||
//一共不是3张图片嘛3+4,默认一进去是第几章3
|
||
return getSwiperList(this.swiperList, {
|
||
circular: this.circular,
|
||
plus: this.plus
|
||
});
|
||
}
|
||
},
|
||
switch: {
|
||
dotsStyles(newVal) {
|
||
this.dots = Object.assign(this.dots, this.dotsStyles);
|
||
},
|
||
|
||
},
|
||
watch: {
|
||
current(){
|
||
this.$emit('change',this.current)
|
||
}
|
||
},
|
||
methods: {
|
||
itemClick(i) {
|
||
this.$emit('itemClick', i);
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
<style lang="scss" scoped>
|
||
.img-row {
|
||
position: relative;
|
||
}
|
||
|
||
.uni-swiper__dots-box {
|
||
position: absolute;
|
||
bottom: 10px;
|
||
left: 0;
|
||
right: 0;
|
||
/* #ifndef APP-NVUE */
|
||
display: flex;
|
||
/* #endif */
|
||
flex: 1;
|
||
flex-direction: row;
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
|
||
.uni-swiper__dots-box-nav {
|
||
flex: 1;
|
||
flex-direction: row;
|
||
justify-content: center;
|
||
align-items: center;
|
||
|
||
}
|
||
|
||
.uni-swiper__dots-item {
|
||
width: 8px;
|
||
border-radius: 100px;
|
||
margin-left: 6px;
|
||
background-color: rgba(0, 0, 0, 0.4);
|
||
/* #ifndef APP-NVUE */
|
||
cursor: pointer;
|
||
/* #endif */
|
||
/* #ifdef H5 */
|
||
// border-width: 5px 0;
|
||
// border-style: solid;
|
||
// border-color: transparent;
|
||
// background-clip: padding-box;
|
||
/* #endif */
|
||
// transition: width 0.2s linear; 不要取消注释,不然会不能变色
|
||
}
|
||
|
||
.uni-swiper__dots-bar {
|
||
border-radius: 100rpx;
|
||
}
|
||
|
||
.uni-swiper__dots-nav {
|
||
bottom: 0px;
|
||
// height: 26px;
|
||
padding: 0px 20rpx;
|
||
/* #ifndef APP-NVUE */
|
||
display: flex;
|
||
/* #endif */
|
||
flex: 1;
|
||
flex-direction: row;
|
||
justify-content: flex-start;
|
||
align-items: center;
|
||
height: 60rpx;
|
||
|
||
}
|
||
|
||
.uni-swiper__dots-nav-item {
|
||
/* overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap; */
|
||
font-size: 28rpx;
|
||
color: #fff;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
|
||
/* #ifndef APP-NVUE */
|
||
overflow: hidden;
|
||
word-break: break-all;
|
||
display: -webkit-box;
|
||
-webkit-box-orient: vertical;
|
||
-webkit-line-clamp: 1;
|
||
/* #endif */
|
||
/* #ifdef APP-NVUE */
|
||
lines: 1;
|
||
/* #endif */
|
||
|
||
}
|
||
|
||
.item-default {
|
||
border-radius: 20rpx;
|
||
transition-property: transform;
|
||
transition-duration: 1s;
|
||
transform: scaleY(0.8);
|
||
}
|
||
|
||
.item-swiper-current {
|
||
transform: scaleY(1);
|
||
}
|
||
</style>
|