iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >vue+uniapp瀑布流布局怎么实现
  • 882
分享到

vue+uniapp瀑布流布局怎么实现

2023-07-05 15:07:39 882人浏览 安东尼
摘要

这篇“Vue+uniapp瀑布流布局怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“vue+uniapp瀑布流布局怎么

这篇“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(图片高度累加比较法)

<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(父元素高度比较法)

每次放入图片需要等待渲染后再重新计算父元素高度,关键代码 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实现

由于uniapp获取元素高度和vue有所区别,造成实现瀑布流方式也需要调整。我们知道uniapp不能通过this.$ref.xx.clientHeight获取元素高度,而需要通过uni.createSelectorQuery().in(this).select(&lsquo;.xxxx&rsquo;).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//方法1this.setWaterFallLayout()//方法2// this.setWaterFallLayout2()}).exec()})},methods: {//方法1通过img.onloadasync setWaterFallLayout() {for (let item of this.imageList) {let img = new Image()img.src = itemtry {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.columnWidthresolve(h)}//加载出错img.onerror = () => {reject('error')}})},//方法2通过uni.getImageInfoasync 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瀑布流布局怎么实现”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网精选频道。

--结束END--

本文标题: vue+uniapp瀑布流布局怎么实现

本文链接: https://www.lsjlt.com/news/352841.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作