Uniapp实现图片瀑布流

7,236 阅读1分钟

「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战」。

关于在uniapp中实现图片瀑布流的方式

如果所示瀑布流即呈现高度不一的图片流体状。

瀑布流.jpg

在uniapp中有这么一个api,uni.getImageInfo,来获取图片的信息,包括宽高等。

1645194111(1).jpg

那么已知图片宽高,由于在移动端本次实现的是两列排布,固定好一个宽度,就变成了x/y=a/bx/y=a/b,令x=已知高度,y=已知宽度,固定宽度a,那么得到的高度(b)就=已知宽度(y)*固定宽度(a)/已知高度(x),然后将其放入两个列表进行排布,再计算列表中放入图片的高度,当左边列表图片高度和小于右边列表图片高度和时,将接下来获取到的图片放入右边列表中。

那么首先定义一个函数来解析获取到的图片,并根据图片的高度放入对应的列表盒子中。

async analysis(imgList){//imgList为拿到的图片数组
        let imgListLength = imgList.length   //定义数组的长度
        let leftList = []           //定义左边空列表
        let rightList = []          //定义右边空列表
        for(let i = 0;i<imgListLength;i++){//循环图片数组
          if(!imgList[i].fileUrl){ //当后台获取到的图片不给返回url时,给定一张默认图片
            imgList[i].fileUrl = 'https:****.jpg'
          }
          let imgBox = await uni.getImageInfo({src:imgList[i].fileUrl})//众所周知,
          //uni.getImageInfo是一个异步的api,所以利用async,await雨大等待执行,用imgBox接收
          let {errMsg} = imgBox[1]      //errMsg为该api返回值
          console.log(this)
          if(errMsg=='getImageInfo:ok'){
            let realWith = imgBox[1].width     //获取到图片原有宽度
            let realHeight = imgBox[1].height  //原有高度
            const guDingWidth = 170            //给定宽度是170,单位在后面补充
            let HQ_hight = ((guDingWidth*realHeight)/realWith)//计算后的高度
            imgList[i].changHeight = HQ_hight
            //将图片丢进列表中
            console.log(this.leftHight)       //this.leftHight定义在data中初始数据为0
            console.log(this.rightHight)      //同样,分别代表列表的存放图片高度
            if(this.leftHight <= this.rightHight){   //当左边高度小于等于右边高度时,将图片放入左边盒子
              this.leftHight = this.leftHight + HQ_hight
              leftList.push(imgList[i])
            }
            else{                                   
              this.rightHight = this.rightHight + HQ_hight//放入盒子的同事计算高度
              rightList.push(imgList[i]) //不然,则放入右边盒子
            }
          }else{
            uni.showToast({            //如果获取图片信息失败则用模板字符串返回报错信息
              icon:'none',
              title:`${errMsg}`,
              duration:2000
            })
          }
          console.log(this.leftHight)
         console.log(this.rightHight)
          
        }
        this.left1 = leftList           //将数据赋值给data数据中
        this.left2 = rightList 
      },

那么这就是对获取到的图片数组做了解析并将图片分别放入到两边列表的过程。由于数据量可能会很大,后端图片做了分页,同样前端展示也需要一部分一部分获取。那么就有在初始时候获取和图片下拉时获取两种。

因为获取图片接口数据有两种,初始和下拉获取图片数据,这里封装成一个函数,方便调用。

1. 初始获得请求数据获取

async getImgList(dataKey){
        let getImg = await this.$request('ap****',dataKey) //通过接口请求参数获取数据
        const {data,code,count,msg} = getImg  //利用es6语法
        code == 0?              //接口获取数据成功
        (
          this.loading = false,      //数据加载结束
          this.finished =true,       
          await this.analysis(data)    //等待上面数据解析完成,
          //并且此时获取到的数据列表被暂存到left1和left2中,
          //表示这一次请求获取到的应该放在盒子中的数据
        ):
        (                             //如果接口错误,范会报错信息
          this.loading = true,
          this.finished =false,
          uni.showToast({
            icon:'none',
            msg:`${msg}`,
            duration:2000
          })
        )
          //等待解析数据完成
        console.log(this.left1)
          //拼接右边数据
      },

初始展示的数据

onLoad() {
      this.loading = true               //loading表示加载样式
      this.finished = false             //finished表示加载完成样式
      this.leftlist = []                //同理,定义初始列表数组
      this.rightlist = []
      this.loading = true
      console.log(this.leftlist,this.leftlist)
      //dataKey所要传输的data数据
      //异步变同步使得push数组有效
      let FirstList = async() =>{                 
        await this.getImgList(this.dataKey)  //调用接口获得图片数据
        this.leftlist.push(...this.left1) //拼接左边数据
        this.rightlist.push(...this.left2)//拼接右边数据
      }
      FirstList()
		},

通过下拉获取数据,利用uniapp的onReachBottom这个api实现下拉

onReachBottom() {
  this.dataKey.page = this.dataKey.page + 1//分页加一
  this.getImgList(this.dataKey)//通过获取图片数据接口再次请求
  this.leftlist.push(...this.left1) //拼接左边数据
  this.rightlist.push(...this.left2)
},

感谢读者大大的阅读,作为一个前端小白,写作的内容多少会有点瑕疵,如果写的文章有不好值得纠正的地方,欢迎各位读者大大们的指正和探讨。