您好,登錄后才能下訂單哦!
這篇“vue+uniapp瀑布流布局怎么實現”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“vue+uniapp瀑布流布局怎么實現”文章吧。
通過動態計算哪一列高度最低,就把圖片放置該列下顯示,直至所有圖片分列完畢
計算哪一列高度最低具體實現過程又分2種方式:
方式1:通過計算每一列每張圖片渲染后高度進行累加就是該列的高度,記錄每列累加高度比較大小
方式2:直接通過圖片父級元素高度(列div)來判斷哪一列最低
區別:方式1無需等待圖片真實渲染完成在比較高度,方式2需要等待圖片真實渲染完成在獲取高度
以左右2列為例
<template> <div class="page"> <!-- 左圖片列表 --> <div class="left" ref="left"> <img class="img" v-for="(item, index) in leftList" :key="index" :src="item" /> </div> <!-- 右圖片列表 --> <div class="right" ref="right"> <img class="img" v-for="(item, index) in rightList" :key="index" :src="item" /> </div> </div> </template>
<style scoped> .page { width: 100%; display: flex; align-items: flex-start; padding: 0 1%; box-sizing: border-box; } .left, .right { margin: 0 auto; width: 48%; } .img { width: 100%; height: auto; margin-bottom: 10px; } </style>
1.方式1(圖片高度累加比較法)
<script> export default { data() { return { imgList: [ "https://img0.baidu.com/it/u=1345303087,1528317222&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=1082", "https://img2.baidu.com/it/u=1893470775,4143435497&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500", "https://img0.baidu.com/it/u=1088754973,1390499664&fm=253&fmt=auto&app=138&f=JPEG?w=335&h=500", "https://img1.baidu.com/it/u=3866290852,3566512524&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500", "https://img2.baidu.com/it/u=1114729443,1120710416&fm=253&fmt=auto&app=138&f=JPEG?w=667&h=500", "https://img0.baidu.com/it/u=1345303087,1528317222&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=1082", "https://img2.baidu.com/it/u=1893470775,4143435497&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500", "https://img2.baidu.com/it/u=1088754973,1390499664&fm=253&fmt=auto&app=138&f=JPEG?w=335&h=500", ], //所有圖片 leftList: [], //左邊列圖片 rightList: [], //右邊列圖片 leftHeight: 0, //左邊列高度 rightHeight: 0, //右邊列高度 columnWidth: 0, //列寬度 }; }, mounted() { this.$nextTick(() => { this.columnWidth = this.$refs.left.clientWidth; this.setWaterFallLayout(); }); }, methods: { //方法1 async setWaterFallLayout() { for (let item of this.imgList) { let img = new Image(); img.src = item; try{ let h = await this.getImgHeight(img);//圖片渲染后高度 if (this.leftHeight <= this.rightHeight) {//左邊列比右邊低,圖片放入左邊 this.leftList.push(item); this.leftHeight += h; } else {//否則,圖片放入右邊 this.rightList.push(item); this.rightHeight += h; } }catch(e){ console.log(e) } } }, //獲取圖片高度 getImgHeight(img) { return new Promise((resolve,reject) => { //圖片加載完成 img.onload = () => { let h = (img.height / img.width) * this.columnWidth;//計算圖片渲染后高度 resolve(h); }; //加載出錯 img.onerror=()=>{ reject('error') } }); }, }, }; </script>
2.方式2(父元素高度比較法)
每次放入圖片需要等待渲染后再重新計算父元素高度,關鍵代碼 await this.$nextTick()
<script> export default { data() { return { imgList: [ "https://img0.baidu.com/it/u=1345303087,1528317222&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=1082", "https://img2.baidu.com/it/u=1893470775,4143435497&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500", "https://img0.baidu.com/it/u=1088754973,1390499664&fm=253&fmt=auto&app=138&f=JPEG?w=335&h=500", "https://img1.baidu.com/it/u=3866290852,3566512524&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500", "https://img2.baidu.com/it/u=1114729443,1120710416&fm=253&fmt=auto&app=138&f=JPEG?w=667&h=500", "https://img0.baidu.com/it/u=1345303087,1528317222&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=1082", "https://img2.baidu.com/it/u=1893470775,4143435497&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500", "https://img2.baidu.com/it/u=1088754973,1390499664&fm=253&fmt=auto&app=138&f=JPEG?w=335&h=500", ], //所有圖片 leftList: [], //左邊列表圖片 rightList: [], //右邊列表圖片 }; }, mounted() { this.$nextTick(() => { this.setWaterFallLayout2(); }); }, methods: { //方法2 async setWaterFallLayout2() { for (let item of this.imgList) { if (this.$refs.left.clientHeight <= this.$refs.right.clientHeight) {//左邊列比右邊低,圖片放入左邊 this.leftList.push(item); } else {//否則圖片放入右邊 this.rightList.push(item); } await this.$nextTick();//等待渲染完成后重新比較左右高度 } }, }, }; </script>
由于uniapp獲取元素高度和vue有所區別,造成實現瀑布流方式也需要調整。我們知道uniapp不能通過this.$ref.xx.clientHeight獲取元素高度,而需要通過uni.createSelectorQuery().in(this).select(‘.xxxx’).boundingClientRect().exec()來獲取,且經過實測當圖片動態加入列后通過該api計算出父元素真實高度是不準確的,所以uniapp瀑布流布局實現方式只能通過方法1(也即圖片高度累加法)進行實現,除了上面方法1通過img.onload來獲取圖片高度外,uniapp還提供uni.getImageInfo方法來更方便獲取圖片高度。
代碼實現
<template> <view class="page"> <view class="left" ref="left"> <image class="image" v-for="(item,i) in leftList" :key="i" :src="item" mode="widthFix"></image> </view> <view class="right" ref="right"> <image class="image" v-for="(item,i) in rightList" :key="i" :src="item" mode="widthFix"></image> </view> </view> </template>
<style lang="scss"> .page { width: 100%; display: flex; align-items: flex-start; padding: 0 1%; box-sizing: border-box; } .left, .right { margin: 0 auto; width: 48%; } .image { width: 100%; height: auto; margin-bottom: 10px; } </style>
<script> export default { data() { return { imageList: [ "https://img0.baidu.com/it/u=1345303087,1528317222&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=1082", "https://img2.baidu.com/it/u=1893470775,4143435497&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500", "https://img0.baidu.com/it/u=1088754973,1390499664&fm=253&fmt=auto&app=138&f=JPEG?w=335&h=500", "https://img1.baidu.com/it/u=3866290852,3566512524&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500", "https://img2.baidu.com/it/u=1114729443,1120710416&fm=253&fmt=auto&app=138&f=JPEG?w=667&h=500", "https://img0.baidu.com/it/u=1345303087,1528317222&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=1082", "https://img2.baidu.com/it/u=1893470775,4143435497&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500", "https://img0.baidu.com/it/u=1088754973,1390499664&fm=253&fmt=auto&app=138&f=JPEG?w=335&h=500", ], //所有圖片 leftList: [], //左邊列圖片 rightList: [], //右邊列圖片 leftHeight: 0, //左邊列高度 rightHeight: 0, //右邊列高度 columnWidth: 0 //列寬度 } }, mounted() { this.$nextTick(() => { uni.createSelectorQuery().in(this).select('.left').boundingClientRect(res => { this.columnWidth = res.width //方法1 this.setWaterFallLayout() //方法2 // this.setWaterFallLayout2() }).exec() }) }, methods: { //方法1通過img.onload async setWaterFallLayout() { for (let item of this.imageList) { let img = new Image() img.src = item try { let h = await this.getImgHeight(img) if (this.leftHeight <= this.rightHeight) { this.leftList.push(item) this.leftHeight += h } else { this.rightList.push(item) this.rightHeight += h } } catch (e) { console.log(e) } } }, //獲取圖片高度 getImgHeight(img) { return new Promise((resolve, reject) => { img.onload = () => { let h = img.height / img.width * this.columnWidth resolve(h) } //加載出錯 img.onerror = () => { reject('error') } }) }, //方法2通過uni.getImageInfo async setWaterFallLayout2() { for (let item of this.imageList) { uni.getImageInfo({ src: item, success: e => { if (this.leftHeight <= this.rightHeight) { this.leftList.push(item) this.leftHeight += e.height } else { this.rightList.push(item) this.rightHeight += e.height } } }) } } }, } </script>
多列實現和2列一樣,動態生成每列圖片數據和記錄每列高度
代碼實現
以最簡單的父元素高度比較法(方式2)為例實現,圖片高度累加比較法(方式1)自行類比實現
<template> <div class="page"> <div class="column" ref="column" v-for="(item, index) in columnList" :key="index" > <img class="img" v-for="(n, i) in item" :key="i" :src="n" /> </div> </div> </template>
<style scoped> .page { width: 100%; display: flex; align-items: flex-start; padding: 0 1%; box-sizing: border-box; } .column { flex: 1; padding: 0 10px; box-sizing: border-box; width: 0; } .img { width: 100%; height: auto; margin-bottom: 10px; } </style>
<script> export default { data() { return { imgList: [ "https://img0.baidu.com/it/u=1345303087,1528317222&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=1082", "https://img2.baidu.com/it/u=1893470775,4143435497&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500", "https://img0.baidu.com/it/u=1088754973,1390499664&fm=253&fmt=auto&app=138&f=JPEG?w=335&h=500", "https://img1.baidu.com/it/u=3866290852,3566512524&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500", "https://img2.baidu.com/it/u=1114729443,1120710416&fm=253&fmt=auto&app=138&f=JPEG?w=667&h=500", "https://img0.baidu.com/it/u=1345303087,1528317222&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=1082", "https://img2.baidu.com/it/u=1893470775,4143435497&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500", "https://img0.baidu.com/it/u=1088754973,1390499664&fm=253&fmt=auto&app=138&f=JPEG?w=335&h=500", "https://img0.baidu.com/it/u=1345303087,1528317222&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=1082", "https://img2.baidu.com/it/u=1893470775,4143435497&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500", ], //所有圖片 columnList: [], //分配后的每列圖片 columWidth: 0, //每列寬度 columnCount: 5, //顯示幾列 }; }, created() { //初始化數據 for (let i = 0; i < this.columnCount; i++) { this.columnList.push([]);//生成每列圖片數組 } }, mounted() { this.$nextTick(()=>{ this.setWaterFallLayout(); }) }, methods: { //瀑布布局 async setWaterFallLayout() { for (let item of this.imgList) { let columnHeight = this.$refs.column.map((item) => item.clientHeight); //每列高度數組 let min = Math.min(...columnHeight); //找出最小高度值 let index = columnHeight.findIndex((item) => item === min); //找出最小高度列的索引 this.columnList[index].push(item);//放入圖片 await this.$nextTick(); //等待渲染完成后重新比較高度 } }, }, }; </script>
以上就是關于“vue+uniapp瀑布流布局怎么實現”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。