vue3.2结合js实现基础瀑布流

212 阅读1分钟

效果

QQ截图20230322083345.png

核心代码

/**
 * @param { string } wrapIdName 容器id(或class)名称
 * @param { string } contentIdName 容器中内容项id(或class)名称
 * @param { number } column 容器中内容展示列数 默认为8
 * @param { number } columnGap 容器中列间隔距离 默认为20
 * @param { number } rowGap 容器中行间隔距离 默认为30
 */
const waterFall = (wrapIdName, contentIdName, columns = 8, columnGap = 20, rowGap = 30) => {
  // 获得内容可用宽度(去除滚动条宽度)
  const wrapContentWidth = document.querySelector(wrapIdName).offsetWidth - 8
  // 间隔空白区域
  const whiteArea = (columns - 1) * columnGap
  // 得到每列宽度(也即每项内容宽度)
  const contentWidth = parseInt((wrapContentWidth - whiteArea) / columns)
  // 得到内容项集合
  const contentList = document.querySelectorAll(contentIdName)
  // 成行内容项高度集合
  const lineConentHeightList = []
  for (let i = 0; i < contentList.length; i++) {
    // 动态设置内容项宽度
    contentList[i].style.width = contentWidth + "px"
    // 获取内容项高度
    const height = contentList[i].clientHeight
    if (i < columns) {
      // 第一行按序布局
      contentList[i].style.top = 0
      contentList[i].style.left = contentWidth * i + columnGap * i + "px"
      // 将行高push到数组
      lineConentHeightList.push(height)
    } else {
      // 其他行
      // 获取数组最小的高度 和 对应索引
      let minHeight = Math.min(...lineConentHeightList)
      let index = lineConentHeightList.findIndex((listH) => listH === minHeight)
      contentList[i].style.top = minHeight + rowGap + "px"
      contentList[i].style.left = (contentWidth + columnGap) * index + "px"
      // 修改最小列的高度 最小列的高度 = 当前自己的高度 + 拼接过来的高度 + 行间距
      lineConentHeightList[index] += height + rowGap
    }
  }
}

实现滚动加载

  <div id="container_scorll" class="container_scorll" @scroll="Scroll">
    <div v-for="item in list1ImgList" :key="item.index" class="item_box" @click="emit('itemClick')">
    </div>
  </div>
//数据集
const list1ImgList = ref([])

const Scroll = (e) => {
  let scrollTop = e.target.scrollTop
  let clientHeight = e.target.clientHeight
  let scrollHeight = e.target.scrollHeight
  if (scrollTop + clientHeight >= scrollHeight - 10) {
    //拼接数据
    list1ImgList.value.push([])
    nextTick(() => {
    //初始化瀑布流
      waterFall(".container_scorll", ".item_box")
    })
  }
}


onMounted(() => {
  nextTick(() => {
  //初始化
    window.onload = function () {
      waterFall(".clubor_item_container", ".item_box")
    }
    window.onresize = function () {
      waterFall(".clubor_item_container", ".item_box")
    }
  })
})