You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
167 lines
3.7 KiB
167 lines
3.7 KiB
<!--本文件由FirstUI授权予内蒙古晟誉网络科技有限责任公司(手机号:15 1 48 22 8 1 08,身份证尾号:1R6T39)专用,请尊重知识产权,勿私下传播,违者追究法律责任。-->
|
|
<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>
|