uni-item-manage/tm-vuetify/components/tm-flowLayout/tm-flowLayout.vue
2023-10-18 15:52:41 +08:00

207 lines
5.6 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>