瀑布流

作者: 学不动了Zzz | 来源:发表于2022-08-29 10:03 被阅读0次

    实现方式

    1.flex配合js
    原理

    列表提前加载一次,计算高度,然后分别加入左右两个列表,最后渲染两个列表
    先加载

    export default defineComponent({
      setup() {
        const loadRef = ref(null)
        const state = reactive({
          loading: false,
          finished: false,
          params: {
            pageSize: 10,
            pageNo: 0
          },
          dataList: [],
          left: {
            list: [],
            height: 0
          },
          right: {
            list: [],
            height: 0
          },
          total: 0
        })
    
        const onLoad = async () => {
          try {
            state.loading = true
            const {
              data: { data, total}
            } = await FetchDataList(state.params)
            // 用于提前加载
            state.dataList = data
            state.total = total
    
            state.params.pageNo++
    
            nextTick(() => {
              // 获取提前加载的dom
              const arr = loadRef.value.querySelectorAll('.item')
    
              datas.forEach((e, i) => {
                // 实际展示的列表,根据高度判断push到对应数组
                const listName =
                  state.left.height <= state.right.height ? 'left' : 'right'
                state[listName].list.push(e)
                state[listName].height += arr[i].offsetHeight
              })
            })
          } finally {
            state.loading = false
          }
        }
    
        return {
          lecturer,
          onLoad,
          ...toRefs(state)
        }
      },
      render() {
        return (
          <List
            vModel={this.loading}
            finished={this.finished}
            onLoad={this.onLoad}
            immediate-check={true}
          >
            <!-- 提前渲染的内容 -->
            <div
              ref="loadRef"
              style="opacity: 0;position: fixed; left: -999px;top: -999px"
            >
              {this.dataList.map(e => (
                <Item data={e} />
              ))}
            </div>
            <!-- 实际展示的内容 -->
            <div class="container">
              <div>
                {this.left.list.map(e => (
                  <Item data={e} />
                ))}
              </div>
              <div>
                {this.right.list.map(e => (
                  <Item data={e} />
                ))}
              </div>
            </div>
          </List>
        )
      }
    })
    
    // style
    .container {
      display: flex;
      padding: 15px 15px 0;
      justify-content: space-between;
      & > div {
        width: 168px;
        display: flex;
        flex-wrap: wrap;
        flex-direction: column;
        counter-reset: items;
        min-height: 100vh;
      }
    }
    
    优点
    • 可以应对内容高度未知的情况
    • 可以分页
    缺点
    • 需要计算,性能有损耗
    2.flex
    .container{
      display: flex;
      flex-wrap: wrap;
      flex-direction: column;
      height: 800px;
    }
    
    优点
    • 无需js配合
    缺点
    • 需要提前知道内容高度,并设置容器高度
    • 不支持分页
    3.column-count
    .container{
      column-count: 2;
      .item {
        break-inside: avoid;
      }
    }
    
    优点
    • 无需js配合
    • 简单,不需要知道内容高度,不需要设置容器高度
    缺点
    • 不支持分页(分页时新加载的内容会展示在第二列的最上面)

    相关文章

      网友评论

          本文标题:瀑布流

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