2023-09-25 18:20:36 +08:00

428 lines
10 KiB
Vue

<template>
<!-- #ifndef APP-NVUE -->
<view
class="yingbing-flip"
:prop="flipProp"
:change:prop="flip.propWatcher"
@touchstart="flip.touchstart"
@touchmove="flip.touchmove"
@touchend="flip.touchend"
@touchcancel="flip.touchcancel"
:style="{
background: bgColor
}">
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<view
class="yingbing-flip"
ref="yingbingFlip"
@touchstart="fliptouchstart"
@touchmove="fliptouchmove"
@touchend="fliptouchend"
:style="{
background: bgColor
}">
<!-- #endif -->
<view
class="yingbing-flip-item"
:class="'yingbing-flip-item_' + item"
v-for="(item, index) in dataSync"
:ref="'yingbingFlipItem_' + item"
:style="{
'background': bgColor,
'transform': item > currentIndex ? translate + '(' + fullSize + ')' : item < currentIndex ? translate + '(-' + fullSize + ')' : '',
'box-shadow': vertical ? '0 0 15rpx rgba(0,0,0,.2)' : ''
}"
:key="item">
<view
class="yingbing-flip-item-content"
:ref="'yingbingFlipItemContent_' + item"
:class="'yingbing-flip-item-content_' + item"
:style="{
'background': bgColor,
'transform': item < currentIndex ? type == 'real' ? translate + '(' + fullSize + ')' : translate + '(0)' : translate + '(0)'
}">
<!-- #ifdef MP -->
<slot v-if="item > -1 && item < count" :name="item"></slot>
<!-- #endif -->
<!-- #ifndef MP -->
<slot v-if="item > -1 && item < count" :item="data[item]" :index="item"></slot>
<!-- #endif -->
</view>
<view
class="yingbing-flip-item-bg"
:ref="'yingbingFlipItemBg_' + item"
:class="'yingbing-flip-item-bg_' + item"
:style="{
background: bgColor,
transform: item < currentIndex && type == 'real' ? translate + '(0)' : translate + '(' + fullSize + ')',
}"></view>
<view
class="yingbing-flip-item-shadow"
:ref="'yingbingFlipItemShadow_' + item"
:class="'yingbing-flip-item-shadow_' + item"
:style="[shadowStyle]"></view>
</view>
<view class="yingbing-flip-pulldown"
:style="[pulldownStyle]" v-if="pulldownable" ref="yingbing_flip_pulldown">
<view class="yingbing-flip-pulldown-item yingbing-flip-pulldown-default" ref="yingbing_flip_pulldown_default">
<slot name="pulldownDefault"></slot>
</view>
<view class="yingbing-flip-pulldown-item yingbing-flip-pulldown-ready" ref="yingbing_flip_pulldown_ready">
<slot name="pulldownReady"></slot>
</view>
<view class="yingbing-flip-pulldown-item yingbing-flip-pulldown-loading" ref="yingbing_flip_pulldown_loading">
<slot name="pulldownLoading"></slot>
</view>
<view class="yingbing-flip-pulldown-item yingbing-flip-pulldown-success" ref="yingbing_flip_pulldown_success">
<slot name="pulldownSuccess"></slot>
</view>
<view class="yingbing-flip-pulldown-item yingbing-flip-pulldown-fail" ref="yingbing_flip_pulldown_fail">
<slot name="pulldownFail"></slot>
</view>
</view>
<view class="yingbing-flip-pullup"
:style="[pullupStyle]" v-if="pullupable" ref="yingbing_flip_pullup">
<view class="yingbing-flip-pullup-item yingbing-flip-pullup-default" ref="yingbing_flip_pullup_default">
<slot name="pullupDefault"></slot>
</view>
<view class="yingbing-flip-pullup-item yingbing-flip-pullup-ready" ref="yingbing_flip_pullup_ready">
<slot name="pullupReady"></slot>
</view>
<view class="yingbing-flip-pullup-item yingbing-flip-pullup-loading" ref="yingbing_flip_pullup_loading">
<slot name="pullupLoading"></slot>
</view>
<view class="yingbing-flip-pullup-item yingbing-flip-pullup-success" ref="yingbing_flip_pullup_success">
<slot name="pullupSuccess"></slot>
</view>
<view class="yingbing-flip-pullup-item yingbing-flip-pullup-fail" ref="yingbing_flip_pullup_fail">
<slot name="pullupFail"></slot>
</view>
</view>
</view>
</template>
<script>
// #ifdef APP-NVUE
import flipBindingx from '../modules/flip_bindingx.js'
// #endif
export default {
// #ifdef APP-NVUE
mixins: [flipBindingx],
// #endif
props: {
data: {
type: Array,
default () {
return new Array
}
},
vertical: {
type: Boolean,
default: false
},
current: {
type: Number,
default: 0
},
//翻页方式
type: {
type: String,
default: 'real'
},
//滑动周期
duration: {
type: Number,
default: 100
},
//容错距离
sliderFault: {
type: Number,
default: 20
},
//背景颜色
bgColor: {
type: String,
default: '#fcd281'
},
//是否关闭点击左右2侧位置翻页
unableClickPage: {
type: Boolean,
default: false
},
// 是否能继续阅读后续章节
readChapterFlag:{
type: Boolean,
default: false
},
//开启下拉刷新
pulldownable: {
type: Boolean,
default: false
},
//下拉刷新高度
pulldownHeight: {
type: Number,
default: 80
},
//开启上拉加载
pullupable: {
type: Boolean,
default: false
},
//上拉加载高度
pullupHeight: {
type: Number,
default: 80
}
},
computed: {
dataSync () {
let arr = []
if ( this.prevIndex >= 0 ) {
arr.push(this.prevIndex)
}
arr.push(this.currentIndex)
if ( this.nextIndex < this.count ) {
arr.push(this.nextIndex)
}
return this.refreshing ? [] : arr.sort((a, b) => b-a)
},
nextIndex () {
return this.currentIndex + 1 > this.count - 1 && this.count > 2 ? 0 : this.currentIndex + 1
},
prevIndex () {
return this.currentIndex - 1 < 0 && this.count > 2 ? this.count - 1 : this.currentIndex - 1
},
count () {
return this.data.length
},
flipProp () {
return {
vertical: this.vertical,
pulldownable: this.pulldownable,
pullupable: this.pullupable,
pulldownHeight: this.pulldownHeight,
pullupHeight: this.pullupHeight,
loadingState: this.loadingState,
duration: this.duration,
unableClickPage: this.unableClickPage,
readChapterFlag: this.readChapterFlag,
nextIndex: this.nextIndex,
prevIndex: this.prevIndex,
currentIndex: this.currentIndex,
type: this.type,
count: this.count,
flipTo: this.flipTo,
sliderFault: this.sliderFault,
translate: this.translate
}
},
pulldownStyle () {
return this.vertical ? {
left: 0,
right: 0,
top: 0,
height: this.pulldownHeight + 'px',
transform: this.translate + '(-' + this.pulldownHeight + 'px)'
} : {
left: 0,
top: 0,
bottom: 0,
width: this.pulldownHeight + 'px',
transform: this.translate + '(-' + this.pulldownHeight + 'px)'
}
},
pullupStyle () {
return this.vertical ? {
left: 0,
right: 0,
bottom: 0,
height: this.pullupHeight + 'px',
transform: this.translate + '(' + this.pullupHeight + 'px)'
} : {
right: 0,
top: 0,
bottom: 0,
width: this.pullupHeight + 'px',
transform: this.translate + '(' + this.pullupHeight + 'px)'
}
},
shadowStyle () {
return this.vertical ? {
bottom: 0,
right: 0,
left: 0,
height: 0,
// #ifdef APP-NVUE
'background-image': 'linear-gradient(to bottom, rgba(255,255,255, 0), rgba(0,0,0,.5))'
// #endif
} : {
top: 0,
bottom: 0,
right: 0,
width: 0,
// #ifdef APP-NVUE
'background-image': 'linear-gradient(to right, rgba(255,255,255, 0), rgba(0,0,0,.5))'
// #endif
}
},
translate () {
return this.vertical ? 'translateY' : 'translateX'
},
fullSize () {
return this.vertical ? '3050rpx' : '750rpx'
}
},
data () {
return {
refreshing: false,
currentIndex: 0,
flipTo: 0,
loadingState: '',
}
},
created() {
this.currentIndex = this.current
},
methods: {
handleFlipChange (value) {
if ( value > 0 ) {
this.currentIndex = this.currentIndex + value > this.count - 1 ? 0 : this.currentIndex + value
} else {
this.currentIndex = this.currentIndex + value < 0 ? this.count - 1 : this.currentIndex + value
}
this.$emit('change', {
current: this.currentIndex,
detail: this.data[this.currentIndex]
})
this.$emit('update:current', this.currentIndex)
},
pullingRefresh (type) {
this.$emit(type, (state) => {
this.loadingState = state
// #ifdef APP-NVUE
this.resetPullingBindingx()
// #endif
})
},
flipToNext () {
// #ifdef APP-NVUE
this.flipToNextBindingX()
// #endif
// #ifndef APP-NVUE
this.flipTo = 0
this.$nextTick(function () {
this.flipTo = 1
})
// #endif
},
flipToPrev () {
// #ifdef APP-NVUE
this.flipToPrevBindingX()
// #endif
// #ifndef APP-NVUE
this.flipTo = 0
this.$nextTick(function () {
this.flipTo = -1
})
// #endif
},
refresh () {
this.refreshing = true
this.$nextTick(function () {
this.currentIndex = this.current
this.refreshing = false
})
},
resetLoading () {
this.loadingState = ''
// #ifdef APP-NVUE
this.resetPullingBindingx()
// #endif
}
},
watch: {
current (newVal) {
console.log(newVal,"newValnewVal")
this.currentIndex = newVal
}
}
}
</script>
<!-- #ifdef APP-VUE || H5 || MP-QQ || MP-WEIXIN -->
<script lang="wxs" module="flip" src="../modules/flip.wxs"></script>
<!-- #endif -->
<style>
.yingbing-flip {
/* #ifdef APP-NVUE */
flex: 1;
/* #endif */
/* #ifndef APP-NVUE */
height: 100%;
/* #endif */
overflow: hidden;
position: relative;
}
.yingbing-flip-item {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
/* #ifndef APP-NVUE */
overflow: hidden;
/* #endif */
}
.yingbing-flip-item-content {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.yingbing-flip-item-bg {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
/* #ifdef APP-NVUE */
box-shadow: 0 0 20rpx rgba(0,0,0,0.2);
/* #endif */
}
.yingbing-flip-item-shadow {
position: absolute;
/* #ifdef APP-NVUE */
opacity: 0.5;
/* #endif */
}
.yingbing-flip-pulldown, .yingbing-flip-pullup {
position: absolute;
}
.yingbing-flip-pulldown-item, .yingbing-flip-pullup-item {
/* #ifndef APP-NVUE */
visibility: hidden;
/* #endif */
/* #ifdef APP-NVUE */
opacity: 0;
/* #endif */
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
/* #ifdef MP */
/deep/ .scoped-ref {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
yingbing-flip {
display: block;
}
/* #endif */
</style>