<template>
<view class="waterfall">
<view id="leftColumn" class="waterfall-column" :style="{ 'margin-right': (spacing / 2) + 'px' }">
<slot name="left-before"></slot>
<slot name="left-column" :list="leftList"></slot>
<slot name="left-after"></slot>
</view>
<view id="rightColumn" class="waterfall-column" :style="{ 'margin-left': (spacing / 2) + 'px' }">
<slot name="right-before"></slot>
<slot name="right-column" :list="rightList"></slot>
<slot name="right-after"></slot>
</view>
</view>
</template>
<script>
export default {
name: "Waterfall",
props: {
data: {
type: Array,
required: true,
default: []
},
interval: {
type: Number,
default: 200
},
spacing: {
type: Number,
default: 15
}
},
data() {
return {
tempList: [],
leftList: [],
rightList: [],
};
},
watch: {
copyFlowList(nValue, oValue) {
const startIndex = Array.isArray(oValue) && oValue.length > 0 ? oValue.length : 0;
this.tempList = this.tempList.concat(this.cloneData(nValue.slice(startIndex)));
this.splitData();
}
},
mounted() {
this.tempList = this.cloneData(this.copyFlowList);
this.splitData();
},
computed: {
copyFlowList() {
return this.cloneData(this.data);
}
},
methods: {
cloneData(data) {
return JSON.parse(JSON.stringify(data));
},
findElement(selector) {
return new Promise((resolve, reject) => {
try {
const query = uni.createSelectorQuery().in(this);
query.select(selector).boundingClientRect().exec(result => {
resolve(result);
});
} catch (error) {
reject(error);
}
});
},
splitData() {
(async () => {
if (this.tempList.length == 0) {
return;
}
const leftColumnRect = (await this.findElement('#leftColumn'))[0];
const rightColumnRect = (await this.findElement('#rightColumn'))[0];
if (!leftColumnRect || !rightColumnRect) {
return;
}
const item = this.tempList[0];
if (!item) {
return;
}
if (leftColumnRect.height < rightColumnRect.height) {
this.leftList.push(item);
} else if (leftColumnRect.height > rightColumnRect.height) {
this.rightList.push(item);
} else {
if (this.leftList.length <= this.rightList.length) {
this.leftList.push(item);
} else {
this.rightList.push(item);
}
}
this.tempList.splice(0, 1);
this.$nextTick(() => {
this.notifyUpdate();
});
if (this.tempList.length > 0) {
setTimeout(() => {
this.splitData();
}, this.interval);
}
})().catch(error => {
console.error(error);
});
},
notifyUpdate() {
this.$emit('waterfallUpdate');
}
}
}
</script>
<style lang="scss">
@import "@/styles/mixin.scss";
.waterfall {
display: flex;
flex-direction: row;
align-items: flex-start;
width: 100%;
.waterfall-column {
display: flex;
flex: 1;
flex-direction: column;
height: auto;
}
}
</style>
<template>
<view class="waterfall-goods-list">
<waterfall :data="data" :spacing="5" :interval="300" @waterfallUpdate="onWaterfallUpdate()">
<template v-slot:left-before>
<release-calendar></release-calendar>
</template>
<template v-slot:left-column="{list}">
<template v-for="(item, index) in list">
<waterfall-goods-item :data="item" :key="index"
@clickGoodsItem="onClickGoodsItem($event)"></waterfall-goods-item>
</template>
</template>
<template v-slot:right-column="{list}">
<template v-for="(item, index) in list">
<waterfall-goods-item :data="item" :key="index"
@clickGoodsItem="onClickGoodsItem($event)"></waterfall-goods-item>
</template>
</template>
</waterfall>
<view class="list-footer">
<text v-if="data.length < total">
数据加载中...
</text>
<text v-if="data.length == total">
- 已经到底了 -
</text>
</view>
</view>
</template>
<script>
import Waterfall from '@/components/waterfall/core/Waterfall.vue';
import WaterfallGoodsItem from '@/components/waterfall/WaterfallGoodsItem.vue';
import ReleaseCalendar from '@/components/ReleaseCalendar.vue';
export default {
name: "WaterfallGoodsList",
components: {
'waterfall': Waterfall,
'waterfall-goods-item': WaterfallGoodsItem,
'release-calendar': ReleaseCalendar,
},
props: {
data: {
type: Array,
required: true,
default: []
},
total: {
type: Number,
default: 20
}
},
data() {
return {
};
},
methods: {
onClickGoodsItem(data) {
if (data.type == 1 || data.type == 3) {
uni.navigateTo({
url: `/pages/subPack/single-product/single-product?activity_id=${data.activity_id}`
});
} else {
uni.navigateTo({
url: `/pages/subPack/raffle/raffle?activity_id=${data.activity_id}`
});
}
},
onWaterfallUpdate() {
this.$emit('waterfallUpdate');
}
}
}
</script>
<style lang="scss">
@import '@/styles/mixin.scss';
@import '@/styles/theme.scss';
.waterfall-goods-list {
width: 100%;
.list-footer {
@include align-center();
width: 100%;
height: 40px;
>text {
display: block;
color: #b2b2b2;
}
}
}
</style>
0 个回复