167 lines
3.7 KiB
Vue
167 lines
3.7 KiB
Vue
<!--本文件由FirstUI授权予新疆天衡创新研究院有限公司(手机号:18 6 1 40 7 2549,身份证尾号:5A07X5)专用,请尊重知识产权,勿私下传播,违者追究法律责任。-->
|
||
<template>
|
||
<view class="fui-waterfall__wrap" :style="{height:height+'px'}">
|
||
<slot></slot>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
name: "fui-waterfall",
|
||
emits: ['init', 'end'],
|
||
props: {
|
||
columnGap: {
|
||
type: [Number, String],
|
||
default: 24
|
||
},
|
||
topGap: {
|
||
type: [Number, String],
|
||
default: 24
|
||
},
|
||
leftGap: {
|
||
type: [Number, String],
|
||
default: 0
|
||
},
|
||
rightGap: {
|
||
type: [Number, String],
|
||
default: 0
|
||
}
|
||
},
|
||
provide() {
|
||
return {
|
||
waterfall: this
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
height: 0,
|
||
itemWidth: 0,
|
||
leftHeight: 0,
|
||
rightHeight: 0,
|
||
tGap: 0,
|
||
lGap: 0,
|
||
x2: 0
|
||
};
|
||
},
|
||
created() {
|
||
this.childrenArr = []
|
||
this.loadedArr = []
|
||
this.initParam()
|
||
},
|
||
// #ifndef VUE3
|
||
beforeDestroy() {
|
||
this.childrenArr = null
|
||
this.loadedArr = null
|
||
},
|
||
// #endif
|
||
// #ifdef VUE3
|
||
beforeUnmount() {
|
||
this.childrenArr = null
|
||
this.loadedArr = null
|
||
},
|
||
// #endif
|
||
methods: {
|
||
getPx(value) {
|
||
let val = parseInt(uni.upx2px(Number(value)))
|
||
return val % 2 === 0 ? val : val + 1
|
||
},
|
||
initParam(callback) {
|
||
this.tGap = this.getPx(this.topGap)
|
||
this.lGap = this.getPx(this.leftGap)
|
||
const colGap = this.getPx(this.columnGap)
|
||
const rGap = this.getPx(this.rightGap)
|
||
const sys = uni.getSystemInfoSync()
|
||
const gap = colGap + this.lGap + rGap;
|
||
this.itemWidth = (sys.windowWidth - gap) / 2
|
||
this.x2 = this.lGap + this.itemWidth + colGap
|
||
callback && callback(this.itemWidth)
|
||
this.$emit('init', {
|
||
itemWidth: this.itemWidth
|
||
})
|
||
},
|
||
//重置加载
|
||
resetLoadmore() {
|
||
this.leftHeight = 0
|
||
this.rightHeight = 0
|
||
this.height = 0
|
||
this.childrenArr = []
|
||
this.loadedArr = []
|
||
},
|
||
getWaterfallInfo(itemHeight, callback) {
|
||
if (!itemHeight) return;
|
||
let x = this.lGap;
|
||
let y = 0;
|
||
let itemGap = 0;
|
||
if (this.leftHeight <= this.rightHeight) {
|
||
y = this.leftHeight;
|
||
|
||
if (this.leftHeight === 0) {
|
||
this.leftHeight += itemHeight;
|
||
} else {
|
||
itemGap = this.tGap;
|
||
y += this.tGap;
|
||
this.leftHeight += itemHeight + this.tGap;
|
||
}
|
||
} else {
|
||
x = this.x2;
|
||
y = this.rightHeight;
|
||
|
||
if (this.rightHeight === 0) {
|
||
this.rightHeight += itemHeight;
|
||
} else {
|
||
itemGap = this.tGap;
|
||
y += this.tGap;
|
||
this.rightHeight += itemHeight + this.tGap;
|
||
}
|
||
}
|
||
callback && callback({
|
||
x,
|
||
y,
|
||
itemGap
|
||
})
|
||
},
|
||
setWaterfallHeight(itemGap) {
|
||
this.height = Math.ceil(Math.max(this.leftHeight, this.rightHeight) + itemGap);
|
||
},
|
||
startSorting() {
|
||
let clen = this.childrenArr.length
|
||
let llen = this.loadedArr.length
|
||
if (clen === llen && llen > 0) {
|
||
let itemGap = 0
|
||
this.childrenArr.forEach((item, index) => {
|
||
this.getWaterfallInfo(item.height, (res) => {
|
||
itemGap = res.itemGap
|
||
// #ifdef APP-NVUE
|
||
item.aniTransForm(res.x, res.y)
|
||
item.transform = `translate(${res.x}px,${res.y}px)`
|
||
// #endif
|
||
// #ifndef APP-NVUE
|
||
item.transform = `translate3d(${res.x}px,${res.y}px,0)`
|
||
// #endif
|
||
setTimeout(() => {
|
||
item.isShow = true
|
||
}, 20)
|
||
})
|
||
})
|
||
this.setWaterfallHeight(itemGap)
|
||
this.childrenArr = []
|
||
this.loadedArr = []
|
||
this.$emit('end', {})
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.fui-waterfall__wrap {
|
||
/* #ifndef APP-NVUE */
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
/* #endif */
|
||
position: relative;
|
||
/* #ifdef APP-NVUE */
|
||
flex: 1;
|
||
/* #endif */
|
||
}
|
||
</style> |