美文网首页vue
vue图片瀑布流组件

vue图片瀑布流组件

作者: 羊驼626 | 来源:发表于2021-05-11 15:53 被阅读0次

    使用

    <template>
      <TheWaterfall :list="list"/>
    </template>
    <script>
      import TheWaterfall from './TheWaterfall.vue'
      export default {
        components: {
          TheWaterfall
        },
        data() {
          return {
            list: [
              {
                  id: 1,
                  url: require('@/tests/images/Rectangle 2031.png'),
                  width: 142,
                  height: 80
              }
            ]
          }
        }
      }
    </script>
    

    TheWaterfall.vue

    <template>
      <div :class="$style['container']" @click="click">
        <div
          :class="$style['item']"
          :style="{ width: `${width}px` }"
          ref="item"
          v-for="item in list"
          :current="current == item.id"
          :id="item.id"
          :key="item.id"
        >
          <img :src="item.url" :id="item.id" alt="" />
        </div>
      </div>
    </template>
    
    <script>
    export default {
      name: 'TheWaterfall',
      props: {
        /**
           * img数组
           * {
           *    id: string,
           *    url: string,
           *    width: number,
           *    height: number
           * }[]
           */
        list: {
          type: Array,
          required: true
        },
        /**
         * 图片的宽度
         */
        width: {
          type: Number,
          required: false,
          default: 142
        },
        /**
         * 瀑布流有多少列
         */
        columns: {
          type: Number,
          required: false,
          default: 2
        },
        /**
         * 图片的右边距
         */
        right: {
          type: Number,
          required: false,
          default: 10
        },
        /**
         * 图片的下边距
         */
        bottom: {
          type: Number,
          required: false,
          default: 10
        }
      },
      data () {
        return {
          current: null
        }
      },
      methods: {
        click (e) {
          this.current = e.target.id
        },
        waterFall () {
          // 1- 确定图片的宽度 - 滚动条宽度
          const columns = this.columns // 默认2 列
          const itemWidth = this.width // 得到item的宽度
          // 设置到item的宽度
    
          const arr = []
    
          this.list.forEach((item, index) => {
            const height = item.height + this.bottom
            const width = item.width
            const bi = itemWidth / width // 获取缩小的比值
            const boxheight = height * bi // 图片的高度*比值 = item的高度
            if (index < columns) {
              // 2- 确定第一行
              this.$refs.item[index].style.top = '0px'
              this.$refs.item[index].style.left = `${
               index
                  ?(itemWidth + this.right) * index
                  : itemWidth * index
              }px`
              arr.push(boxheight)
            } else {
              // 其他行
              // 3- 找到数组中最小高度  和 它的索引
              let minHeight = arr[0]
              let min = 0
              for (let j = 0; j < arr.length; j++) {
                if (minHeight > arr[j]) {
                  minHeight = arr[j]
                  min = j
                }
              }
              // 4- 设置下一行的第一个盒子位置
              // top值就是最小列的高度
              this.$refs.item[index].style.top = `${arr[min]}px`
              this.$refs.item[index].style.left = this.$refs.item[min].style.left
    
              // 5- 修改最小列的高度
              // 最小列的高度 = 当前自己的高度 + 拼接过来的高度
              arr[min] = arr[min] + boxheight
            }
          })
        }
      },
      mounted () {
        this.waterFall()
      }
    }
    </script>
    
    <style lang="less" module>
    .container {
      width: 100%;
      position: relative;
      height: 100vh;
      background: #fff;
      .item {
        z-index: 10;
        transition: 0.25s;
        overflow: hidden;
        position: absolute;
        &[current="true"] {
          outline: 1px solid #3307fe;
          box-sizing: border-box;
        }
        img {
          width: 100%;
          height: 100%;
        }
      }
    }
    </style>
    
    

    相关文章

      网友评论

        本文标题:vue图片瀑布流组件

        本文链接:https://www.haomeiwen.com/subject/cgxndltx.html