You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

207 lines
5.6 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="tm-flowLayout relative">
<view class="tm-flowLayout-hidden absolute fulled" >
<view v-for="(item, index) in list2" :key="index" style="width: 350rpx;" :class="'tm-flowLayout-hidden-'+index" >
<tm-images @error="loadimg($event,false,index)" @load="loadimg($event,true,index)" :src="item.image"></tm-images>
</view>
</view>
<view class="tm-flowLayout-cm flex-between">
<view class="tm-flowLayout-left" style="width: 48.6%;">
<block v-for="(item, index) in dataList[0]" :key="index">
<view @click.stop="onclick(index,0)" class="tm-flowLayout-item mb-20 fulled" :class="['tm-flowLayout-item_'+index]" >
<slot name="left" :hdata="{item:item,dirIndex:0,childrenIndex:index}">
<tm-images v-if="item.image" :src="item.image"></tm-images>
</slot>
</view>
</block>
</view>
<view class="tm-flowLayout-right" style="width: 48.6%;">
<block v-for="(item, index) in dataList[1]" :key="index">
<view @click.stop="onclick(index,1)" class="tm-flowLayout-item mb-20 fulled" :class="['tm-flowLayout-item_'+index]">
<slot name="right" :hdata="{item:item,dirIndex:1,childrenIndex:index}">
<tm-images v-if="item.image" :src="item.image"></tm-images>
</slot>
</view>
</block>
</view>
</view>
<view v-if="isLoading" class="flex-shrink fulled">
<tm-loadding></tm-loadding>
</view>
</view>
</template>
<script>
/**
* 瀑布流组件
* @property {Function} click 点击项目时触发
* @property {Function} load 当前列表加载完成发出的事件。
* @property {String} model = [rank|desc] desc下正时排序所有加载完成再进行显示,rank随机哪个先加载哪个先排前面。
*/
import tmImages from "@/tm-vuetify/components/tm-images/tm-images.vue"
import tmLoadding from "@/tm-vuetify/components/tm-loadding/tm-loadding.vue"
import tmIcons from "@/tm-vuetify/components/tm-icons/tm-icons.vue"
export default {
components:{tmImages,tmLoadding,tmIcons},
name: 'tm-flowLayout',
props:{
model:{
type:String,
default:'rank' //desc下正时排序所有加载完成再进行显示,rank随机哪个先加载哪个先排前面。
}
},
data() {
return {
list2:[],
dataList:[
[],[]
],
colHeight:[0,0],
minWidth:0,
isLoading:true,
};
},
async mounted() {
let p = await this.$Querey('.tm-flowLayout-left').catch(e=>{});
this.minWidth = p[0].width;
},
methods: {
onclick(index,dirIndex){
this.$emit('click',
{
childrenIndex:index,
dirIndex:dirIndex,
item:this.dataList[dirIndex][index]
});
},
//修改或者替换列表数据
changeItemData(dirIndex,childrenIndex,item){
this.dataList[dirIndex].splice(childrenIndex,1,item);
},
//删除一项列表数据
delItemData(dirIndex,childrenIndex){
this.colHeight.splice(dirIndex,1,this.colHeight[dirIndex] - this.dataList[dirIndex][childrenIndex].height)
this.dataList[dirIndex].splice(childrenIndex,1);
this.list2.splice(this.dataList[dirIndex][childrenIndex].index,1);
this.$nextTick(function(){
this.sucessRank();
})
},
//向列表添加数据
pushData(list){
let prIdx_i = this.list2.length;
if(!Array.isArray(list)||typeof list =='undefined'){
return false;
}
for(let i=0;i<list.length;i++){
this.list2.push({
index:i+prIdx_i,
isLoad:false,
image:"",
width:0,
height:0,
...list[i]
})
}
},
//获取内部列表数据
getDataList(){
return this.dataList;
},
async loadimg(event,isLoad,index) {
// console.log(event,index);
this.isLoading = true;
let ps = this.list2[index];
ps.isLoad = true;
if(isLoad==false){
ps.width = this.minWidth;
ps.height = this.minWidth;
}else{
ps.width = this.minWidth;
ps.height = ps.height+event.height;
}
if(this.list2.length==0&&this.dataList[0].length==0&&this.dataList[1].length==0){
this.isLoading = false;
return;
}
this.list2.splice(index,1,ps);
if(this.model=='desc'){
this.sucessRank();
}else if(this.model == 'rank'){
let indexCol = this.colHeight[0]<=this.colHeight[1]?0:1;
this.dataList[indexCol].push(this.list2[index]);
this.colHeight.splice(indexCol,1,this.colHeight[indexCol]+this.list2[index].height);
if(this.isAllLoading()===false) return;
this.isLoading = false;
}
},
isAllLoading(){
let isAllload = true;
for(let i=0;i<this.list2.length;i++){
if(this.list2[i].isLoad===false){
isAllload = false;
break;
}
}
if(isAllload===true){
// 当前列表加载完成发出的事件。
this.$emit('load',this.dataList)
}
return isAllload;
},
sucessRank(){
if(this.isAllLoading()===false) return;
this.isLoading = false;
for(let i=0;i<this.list2.length;i++){
// let p = await this.getLeftRightHeight();
let index = this.colHeight[0]<=this.colHeight[1]?0:1;
this.dataList[index].push(this.list2[i]);
this.colHeight.splice(index,1,this.colHeight[index]+this.list2[i].height)
}
},
//清空瀑布流数据 。
clear(){
this.list2 = [];
this.dataList = [[],[]];
this.isLoading = false;
},
getLeftRightHeight(index){
let t = this;
return new Promise((resolve,rejecvt)=>{
let q = uni.createSelectorQuery().in(t);
q.select(".tm-flowLayout-left").boundingClientRect();
q.select(".tm-flowLayout-right").boundingClientRect();
q.exec((res)=>{
resolve([res[0].height,res[1].height])
})
})
}
},
};
</script>
<style lang="scss">
.tm-flowLayout {
.tm-flowLayout-hidden{
width: 100%;
height: 100px;
overflow-y: auto;
left: -300%;
top: 0;
}
.tm-flowLayout-cm{
align-items: flex-start;
}
}
</style>