网页效果 - 虚拟滚动列表

一、虚拟滚动列表

虚拟列表的意思就是在数据量超大的情况下,页面只渲染可视范围的列表,减少dom数量,控制页面性能的效果。

二、具体实现

talk is cheap, show me the code.

<template>
  <div class="virtual-list">
    <h1>虚拟列表</h1>

    <div class="list-view" ref="scrollBox" @scroll="handleScroll">
      <div
        class="list-view-phantom"
        :style="{
          height: contentHeight
        }"
      >
        <div ref="content" class="list-view-content">
          <div
            class="list-view-item"
            :style="{
              height: itemHeight + 'px'
            }"
            v-for="item in visibleData"
            :key="item"
            @click="itemClick(item)"
          >
            {{ item }}
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      datalist: [],
      itemHeight: 30,
      visibleData: []
    };
  },
  mounted() {
    // 创建一个贼大的数据数组
    for (let i = 0; i < 10000; i++) {
      this.datalist.push(i);
    }
    this.updateVisibleData();
  },
  computed: {
    contentHeight() {
      return this.datalist.length * this.itemHeight + "px";
    }
  },
  methods: {
    scrollview() {
      const scrollTop = this.$refs.container.scrollTop;
      console.log(scrollTop);
    },
    updateVisibleData(scrollTop = 0) {
      // 计算能显示多少个
      const visibleCount = Math.ceil(
        this.$refs.scrollBox.clientHeight / this.itemHeight
      );
      // 计算可视区域第一个的数组下标
      const start = Math.floor(scrollTop / this.itemHeight);
      // 计算可视区域最后一个的数组下标
      const end = start + visibleCount;
      // 截取可视数组
      this.visibleData = this.datalist.slice(start, end);
      // 设置窗口偏移的量 可视窗口的第一个*item的高度
      this.$refs.content.style.webkitTransform = `translate3d(0, ${start *
        this.itemHeight}px, 0)`;
    },
    handleScroll() {
      // 优化方向,可以节流一下
      const scrollTop = this.$refs.scrollBox.scrollTop;
      this.updateVisibleData(scrollTop);
    },
    itemClick(item) {
      console.log(item);
    }
  }
};
</script>

<style lang="less" scoped>
.viewport {
  width: 300px;
  height: 400px;
  overflow: auto;

  .container {
    height: 6000px;

    .item {
      width: 100%;
      height: 50px;
      border: solid 1px red;
    }
  }
}
.list-view {
  height: 400px;
  overflow: auto;
  position: relative;
  border: 1px solid #aaa;
}

.list-view-phantom {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  z-index: -1;
}

.list-view-content {
  left: 0;
  right: 0;
  top: 0;
  position: absolute;
}

.list-view-item {
  padding: 5px;
  color: #666;
  line-height: 30px;
  box-sizing: border-box;
  z-index: 1;
  cursor: pointer;
}
</style>

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值