vue3 小满zs教学 瀑布流练习

瀑布流练习题

0. 瀑布流的形成

各种高度不同的方块平铺。需要注意的是,第二行开始,选高度最小的方块位置插入新的方块,即需要记住当前高度数组。

1. 父组件 瀑布流的容器

这里的number是为了验证是否如开头所言,插入选取位置最矮的

<template>
  <WaterFall :list="list"></WaterFall>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue'
import WaterFall from '@/components/WaterFallCom/WaterFall/index.vue'

const list = [
  { height: 300, background: 'red' },
  { height: 400, background: 'pink' },
  { height: 100, background: 'black' },
  { height: 200, background: 'purple' },
  { height: 700, background: 'yellow' },
  { height: 800, background: 'blue' },
  { height: 900, background: 'grey' },
  // 第二轮
  { height: 110, background: 'grey' },
  { height: 420, background: 'black' },
  { height: 210, background: 'pink' },
  { height: 290, background: 'blue' },
  { height: 510, background: 'yellow' },
  { height: 300, background: 'green' },
  { height: 100, background: 'red' },
  // 第三轮
  { height: 800, background: 'red' },
  { height: 100, background: 'pink' },
  { height: 50, background: 'black' },
  { height: 120, background: 'purple' },
  { height: 300, background: 'yellow' },
  { height: 400, background: 'blue' },
  { height: 510, background: 'grey' },
  // 第四轮
  { height: 300, background: 'red' },
  { height: 400, background: 'pink' },
  { height: 100, background: 'black' },
  { height: 200, background: 'purple' },
  { height: 700, background: 'yellow' },
  { height: 800, background: 'blue' },
  { height: 900, background: 'grey' }
].map((item, i) => ({ ...item, number: i }))
</script>

<style scoped lang="scss"></style>

2. 子组件 绘制瀑布流方块

<template>
  <div class="wraps">
    <div
      class="items"
      :style="{
        height: item.height + 'px',
        width: item.width + 'px',
        top: item.top + 'px',
        left: item.left + 'px',
        background: item.background
      }"
      v-for="item in waterFallList"
    >
      {{ item.number }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
// 从父组件中获得值
const props = defineProps<{ list: any[] }>()
const originList = props.list
const waterFallList = reactive([])

const onInit = () => {
  const heightList: any[] = []
  const width = 130
  // 获得可视宽度
  const x = document.body.clientWidth
  // 一行能容纳的个数
  const column = Math.floor(x / width)
  const originTop = 10

  for (let i = 0; i < originList.length; i++) {
    // 第一排
    const isFirstFloor = i < column
    if (isFirstFloor) {
      originList[i].top = originTop
      originList[i].left = i * width
      // 顶部高度
      heightList.push(originList[i].height + originTop)
      // 放入瀑布流数组中
      waterFallList.push(originList[i])
    } else {
      // 往后的需要注意维护高度数组,找最小的高度插入
      // 找出当前最小的高度,插入新的方块
      let current = heightList[0] // 比大小第一个
      let minIndex = 0 // 默认序号是0
      heightList.forEach((h, j) => {
        // 将最小的保存
        if (h < current) {
          current = h
          minIndex = j
        }
      })
      // 当前找出的最小高度 + 顶格间距
      originList[i].top = current + originTop
      // 这里的左侧间距,是放置在最矮方块的下一行
      originList[i].left = minIndex * width
      // 同列上一个最小高度方块的高度 + 这一个方块的高度 + 两者之间间隔
      heightList[minIndex] = heightList[minIndex] + originList[i].height + 20
      // 将定位完成的方块 放入瀑布流中
      waterFallList.push(originList[i])
    }
  }
}

onMounted(() => {
  window.onresize = () => onInit()
  onInit()
})
</script>

<style scoped lang="scss">
// 子绝父相能够使子节点按照父节点的标准进行绝对定位.
// 父级需要占有位置,因此是相对定位,子盒子不需要占有位置,则是绝对定位
.wraps {
  position: relative;
  .items {
    position: absolute;
    width: 120px;
  }
}
</style>

3. 实际图

pkJCfqx.md.png

posted @ 2024-06-03 17:43  乐盘游  阅读(17)  评论(0编辑  收藏  举报