vue使用瀑布流加载图片

页面展示代码

<!-- 外层盒子  -->
        <div class="Waterfall wf-content" @scroll="handleScroll">
          <!-- 图片外层盒子 遍历图片数组 -->
          <div class="wf-item" v-for="(item, index) in animallist" :key="index" @click="summary(item.latinName)">
            <!-- @load图片加载完成再触发方法 -->
            <!-- <img :src="item.imageUrl" @load="imageonload" alt="" /> -->
            <el-image @error="errorImg($event)" v-if="item.imageUrl" @load="imageonload" :src="item.imageUrl" alt=""> </el-image>
            <el-image @error="errorImg($event)" v-if="!item.imageUrl" @load="imageonload" :src="defaultImageUrl" alt=""> </el-image>
            <div>
              <h4>
                {{ item.name }}
                <el-tooltip  effect="light" content="信息来源:云南省生物物种名录">
                  <i class="el-icon-question" style="color: var(--m-main-color)"></i>
                </el-tooltip>
              </h4>
              <em>{{ item.latinName }}</em>
            </div>
          </div>
        </div>

css

.Waterfall {
  width: 100%;
  margin: 0 auto;
  position: relative;
  height: 60vh; /* 设置一个固定的高度 */
  overflow-x: hidden; /* 开启垂直滚动 */
  overflow-y: auto; /* 开启垂直滚动 */
}
.wf-item {
  position: absolute;
  border: 5px solid white;
  box-shadow: -3px 2px 5px rgba(0, 0, 0, 0.5);
  cursor: pointer;
}
.wf-item img {
  height: 100%;
  width: 100%;
}

方法

handleScroll(event) {
      const { scrollTop, clientHeight, scrollHeight } = event.target
      // 当滚动条到达底部时,距离顶部的距离加上客户区的高度等于整个滚动区的高度
      const isBottom = scrollTop + clientHeight >= scrollHeight
      if (isBottom) {
        // 滚动条到达底部的操作
        //console.log('滚动条已经到达底部');
        this.pageNum += 1
        getSpeciesByType({ speciesType: this.selectLabel, speciesSelect: this.select, pageNum: this.pageNum, pageSize: this.pageSize }).then((response) => {
          if (this.total === this.count) {
            this.isLoad = false
            this.$message.success('信息已加载完成!暂无更多数据')
          }
          if (this.isLoad) {
            for (let item of response.data.data.rows) {
              this.count++
              this.animallist.push(item)
            }
          }
        })
      }
    },
    // 图片加载完成之后调用方法中的类传参构建瀑布流页面
    imageonload() {
      new Water({
        // 作用元素
        el: '.wf-content',
        // 列
        column: 6,
        // 间距
        gap: 20
      })
    },
    errorImg(e) {
      // console.log(e.target.src,"法1")
      // console.log(e.srcElement.src,"法2")
      e.srcElement.src = 'http://172.16.7.153:9000/biomap/duitang.gif'
      //这一句没用,如果默认图片的路径错了还是会一直闪屏,在方法的前面加个.once只让它执行一次也没用
      e.srcElement.onerror = null //防止闪图
    },

新建一个Water.js文件,在页面种引入

export class Water{
    // 工厂模式给传入元素配置参数 
    constructor(options){
        this.$options = options
        // 最小高度
        this.miniHeight = []
        // 私有方法 
        this.__init()
    }
    __init() {
        // 获取外层盒子下的所以子元素 也就是图片外层的盒子 
        this.items = document.querySelector(this.$options.el).children
        // 添加列
        this.column = this.$options.column
        this.gap = this.$options.gap
        // 元素宽度减去当前的间距*3除去当前的列得到元素的宽度 也就是根据页面宽度一行可以放几张图片
        this.itemWidth = (document.querySelector(this.$options.el).offsetWidth - this.gap * 3) / this.column
        this.__render()
    }
    __render() { 
        // 把子元素数组化遍历 
        [...this.items].forEach((value,index) => {
            // 把提取的元素宽度赋值 
            value.style.width = this.itemWidth + "px"
            if (index < this.column) {
                value.style.top = "0px"
                // 当前元素的宽度加上边距 * 下标
                value.style.left = (this.itemWidth + this.gap) * index + "px"
                // 把元素的高度push到数组里就是index最小的高度 
                this.miniHeight.push(value.offsetHeight)
            } else {
                // 这部分是第二行
                this.miniIndex = this.__getMiniIndex()
                // 元素的上距离 = 最小上距离 加上边距
                value.style.top = this.miniHeight[this.miniIndex] + this.gap + "px"
                // 左距离=元素宽度加上边距*索引 
                value.style.left = (this.itemWidth + this.gap) * this.miniIndex + "px"
                this.miniHeight[this.miniIndex] = this.miniHeight[this.miniIndex] + value.offsetHeight + this.gap
            }
        })
    }
    __getMiniIndex() {
        return this.miniHeight.indexOf(Math.min(...this.miniHeight))
    }
}

完整代码如下:

<template>
<div class="Waterfall wf-content" @scroll="handleScroll">
          <!-- 图片外层盒子 遍历图片数组 -->
          <div class="wf-item" v-for="(item, index) in animallist" :key="index" @click="summary(item.latinName)">
            <!-- @load图片加载完成再触发方法 -->
            <!-- <img :src="item.imageUrl" @load="imageonload" alt="" /> -->
            <el-image @error="errorImg($event)" v-if="item.imageUrl" @load="imageonload" :src="item.imageUrl" alt=""> </el-image>
            <el-image @error="errorImg($event)" v-if="!item.imageUrl" @load="imageonload" :src="defaultImageUrl" alt=""> </el-image>
            <div>
              <h4>
                {{ item.name }}
                <el-tooltip v-if="select != '1-6'" effect="light" content="信息来源:云南省生物物种名录">
                  <i class="el-icon-question" style="color: var(--m-main-color)"></i>
                </el-tooltip>
                <el-tooltip v-if="select === '1-6'" effect="light" content="外来入侵物种名录">
                  <i class="el-icon-question" style="color: var(--m-main-color)"></i>
                </el-tooltip>
              </h4>
              <em>{{ item.latinName }}</em>
            </div>
          </div>
        </div>
</template>
import {  getSpeciesByType } from '@/api/maphttp' //查询图片的接口自行定义
import { Water } from '@/api/Water'
export default {
  name: 'SpeciesList',
  components: {
    RootNav,
    Foot
  },
  data() {
    return {
      total: 2,
      pageNum: 1,
      pageSize: 12,
      defaultImageUrl: '/defaultImage.jpg',
      animallist: [],
      count: 0
    }
  },
  created() {
    this.$nextTick(() => {
      getSpeciesByType({ speciesType: '', speciesSelect: '', pageNum: this.pageNum, pageSize: this.pageSize }).then((response) => {
        this.animallist = response.data.data.rows
        this.total = response.data.data.total
      })
    })
  },
  methods: {
    handleScroll(event) {
      const { scrollTop, clientHeight, scrollHeight } = event.target
      // 当滚动条到达底部时,距离顶部的距离加上客户区的高度等于整个滚动区的高度
      const isBottom = scrollTop + clientHeight >= scrollHeight
      if (isBottom) {
        // 滚动条到达底部的操作
        //console.log('滚动条已经到达底部');
        this.pageNum += 1
        getSpeciesByType({ speciesType: this.selectLabel, speciesSelect: this.select, pageNum: this.pageNum, pageSize: this.pageSize }).then((response) => {
          if (this.total === this.count) {
            this.isLoad = false
            this.$message.success('信息已加载完成!暂无更多数据')
          }
          if (this.isLoad) {
            for (let item of response.data.data.rows) {
              this.count++
              this.animallist.push(item)
            }
          }
        })
      }
    },
    // 图片加载完成之后调用方法中的类传参构建瀑布流页面
    imageonload() {
      new Water({
        // 作用元素
        el: '.wf-content',
        // 列
        column: 6,
        // 间距
        gap: 20
      })
    },
    errorImg(e) {
      // console.log(e.target.src,"法1")
      // console.log(e.srcElement.src,"法2")
      e.srcElement.src = 'http://172.16.7.153:9000/biomap/duitang.gif'
      //这一句没用,如果默认图片的路径错了还是会一直闪屏,在方法的前面加个.once只让它执行一次也没用
      e.srcElement.onerror = null //防止闪图
    },
 }
 <style scoped>
 .Waterfall {
  width: 100%;
  margin: 0 auto;
  position: relative;
  height: 60vh; /* 设置一个固定的高度 */
  overflow-x: hidden; /* 开启垂直滚动 */
  overflow-y: auto; /* 开启垂直滚动 */
}
.wf-item {
  position: absolute;
  border: 5px solid white;
  box-shadow: -3px 2px 5px rgba(0, 0, 0, 0.5);
  cursor: pointer;
}
.wf-item img {
  height: 100%;
  width: 100%;
}
</style>
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值