uniapp小程序實現(xiàn)瀑布流布局的思路與代碼
一、前言
現(xiàn)在寫瀑布流算不算是炒冷飯啊?
我不管, 我就要寫,誰也別想攔我。
瀑布流應該算是很常見的一種布局方法了,大致的思路也很好理解, 但是在小程序里面確有另外需要考慮的幾個問題。
問題1:uniapp是基于Vue的,所以不好直接操作DOM。
問題2:uniapp基于Vue,但也做了一些修改,所以不好拿ref來操作
二、先說思路
為了保證文章的長度,以及有些小伙伴對瀑布流的基本思路不是很了解,所以先講講瀑布流的思路,先看下圖。

可以看到,商品的圖片高度是不一致的,再加上商品標題的行數(shù)不一致,最終呈現(xiàn)的效果是交錯排列的。
之前在開發(fā)過程中,我也試過用CSS的Flex布局,Column布局來實現(xiàn),勉強能實現(xiàn)同樣的效果,但是最終對接后臺要考慮商品的熱度優(yōu)先,所以只能放棄。
Flex實現(xiàn)缺點:使用Flex布局并不能準確計算高度來插入商品。
Column實現(xiàn)缺點:使用Column布局不好操作先后順序。
PS:如果對產品排序沒有要求的話, 可以考慮純CSS實現(xiàn),這里不多贅述,掘金里很多的。
三、核心代碼
如題,本文對于瀑布流的實現(xiàn)是基于uniapp開發(fā)小程序的,如果期望JS原生實現(xiàn),本文的很多思路是需要修改的。
先解答部分疑惑:
因為無法通過$refs獲取到列的高度,所以代碼是通過Image標簽的@load時間先加載一次圖片,并將圖片的寬高等信息傳遞給方法。
// component/waterfall.vue
<template>
<view class="waterfall">
<view hidden>
// 用JS原生實現(xiàn)時可以直接用for循環(huán)插入,然后獲取列高度
// 這里通過載入圖片調用方法, 默認傳參帶有圖片信息,可以獲得圖片高度
<block v-for(item in imgList" :key="item.id">
<image :src="item.url" @load="loadImg" ></iamge>
</block>
</view>
<view class="list" v-for="(list, key) in waterfall" :key="key">
<navigator url="https://www.baidu.com" v-for="item in list.list" :key="item.id">
<image :src="item.url" mode="widthFix"></image>
<view class="shop-info">
/* 標題等信息,略 */
</view>
</navigator>
</view>
</view>
</template>
<script>
export default {
// 抽出為單獨的組件,所以數(shù)據(jù)來源于父組件傳遞,也可以是當前組件請求API
props: { imgList: Array },
data(){
return {
lists: [], // 備份imgList用的數(shù)組,方便操作
waterfall: [
// 用于記錄當前列的高度,不在方法中保存是為了上拉獲取新數(shù)據(jù)也能使用
// 因為默認手機顯示,可以固定兩列
// 如果是做自適應或者電腦端多列,可以動態(tài)插入實現(xiàn)多列
{
height: 0,
list: []
},{
height: 0,
list: []
}
]
}
},
created(){
this.lists = this.imgList; // Vue創(chuàng)建data后立即備份
},
watch(){
// 監(jiān)聽數(shù)據(jù)源,如果有新值傳入,則用lists數(shù)組備份
imgList(data){ data.length && this.lists.push(...data); }
},
methods: {
loadImg(ev){
let Root = this.waterfall;
let height = e.detail.height;
// 根據(jù)當前高度決定將新數(shù)據(jù)給誰,并更新列高度;優(yōu)先插入左側
if(Root[0].height <= Root[1].height){
// 考慮熱度優(yōu)先的問題, 所以用的是shift()方法推出頭部數(shù)據(jù)。
Root[0].list.push(this.lists.shift())
Root[0].height += height;
} else {
Root[1].list.push(this.lists.shift())
Root[1].height += height;
}
}
}
}
</script>
至此,核心代碼就完成了。
PS:因為要借由image的@load事件來觸發(fā)方法,所以大量加載勢必會影響性能,所以要自己做點取舍了。
四、總結
希望如果有小伙伴看完這篇文章之后,決定使用這個方法時,能記得一件事,這個寫法可能有性能問題方面的影響,能在這方面下功夫去深入研究下。
到此這篇關于uniapp小程序實現(xiàn)瀑布流布局的思路與代碼的文章就介紹到這了,更多相關uniapp小程序瀑布流布局內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
JS中的THIS和WINDOW.EVENT.SRCELEMENT詳解
對于js初學著必須理解this和srcElement的應用,這也是面試中經??嫉降?。下面我們就通過幾個示例來詳細了解下2015-05-05
Javascript Event事件中IE與標準DOM的比較
說是IE與DOM的比較,其實還是瀏覽器之間的比較,眾多的瀏覽器中,IE獨樹一幟,并且占有大部分用戶市場,后來的標準DOM雖然不少優(yōu)點之處,但畢竟一般用戶不關心也不知道這些,代碼編寫過程中,往往需要兼顧多個瀏覽器。2010-04-04

