基于vue实现页面滚动加载的示例详解

 更新时间:2024年01月12日 11:24:17   作者:loyd3  
页面内容太多会导致加载速度过慢,这时可考虑使用滚动加载即还没有出现在可视范围内的内容块先不加载,出现后再加载,所以本文给大家介绍了基于vue实现页面滚动加载的示例,需要的朋友可以参考下

页面内容太多会导致加载速度过慢,这时可考虑使用滚动加载即还没有出现在可视范围内的内容块先不加载,出现后再加载
基本思路就是判断元素是否出现在浏览器的可视区域,出现了就加载请求接口加载内容。但是要求内容块有最小高度。

具体代码如下

<template>
  <div>
    <div
      v-loading.fullscreen.lock="loading"
      class="page"
      id="tablist"
      @scroll="listScroll"
    >
      <div
        class="item"
        v-for="(item, i) in testData"
        :key="i"
        :class="i % 2 == 0 ? 'gray' : 'white'"
        :id="item.id"
      >
        {{ item.name }}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "ScrollLoadingSample",
  props: {},
  data() {
    return {
      flag: true, // 开关
      loading: false, // loading加载
      testData: [], // 列表数据
      targetIndex: 0,
      nextId: "",
    };
  },
  mounted() {
    this.initData();
  },
  methods: {
    initData() {
      this.testData = [
        {
          id: "test-1",
          name: "区块1",
          // 要加载的方法名
          function: "loadTest1",
          // 方法是否加载了
          isLoaded: false,
        },
        {
          id: "test-2",
          name: "区块2",
          function: "loadTest2",
          isLoaded: false,
        },
        {
          id: "test-3",
          name: "区块3",
          function: "loadTest3",
          isLoaded: false,
        },
        {
          id: "test-4",
          name: "区块4",
          function: "loadTest4",
          isLoaded: false,
        },
        {
          id: "test-5",
          name: "区块5",
          function: "loadTest5",
          isLoaded: false,
        },
        {
          id: "test-6",
          name: "区块6",
          function: "loadTest6",
          isLoaded: false,
        },
      ];
      this.$nextTick(() => {
        this.loadPage();
      });
    },
    //判断元素是否在可视区域
    isElementInViewport(id) {
      let el = document.getElementById(id);
      //获取元素是否在可视区域
      let rect = el.getBoundingClientRect();
      return (
        rect.top + rect.height / 2 <=
          (window.innerHeight || document.documentElement.clientHeight) &&
        rect.bottom > 0
      );
    },

    // 初次加载页面时
    loadPage() {
      for (let i = 0; i < this.testData.length; i++) {
        if (this.isElementInViewport(this.testData[i]["id"])) {
          this.loadFunctionByName(this.testData[i]["function"]);
          this.testData[i]["isLoaded"] = true;
        } else {
          this.targetIndex = i;
          // 最开始没出现在页面上的id
          this.nextId = this.testData[this.targetIndex]["id"];
          break;
        } 
      }
    },
    // 页面滑动
    listScroll() {
      for (let i = this.targetIndex; i < this.testData.length; i++) {
        // 如果出现在页面上
        if (this.isElementInViewport(this.testData[i]["id"])) {
          // 如果方法没有加载
          if (!this.testData[i]["isLoaded"]) {
            this.loadFunctionByName(this.testData[i]["function"]);
            this.testData[i]["isLoaded"] = true;
          }
        } else {
          // 如果没有出现在页面上
          this.targetIndex = i;
          this.nextId = this.testData[this.targetIndex]["id"];
          break;
        }
      }
    },
    // 根据方法名加载
    loadFunctionByName(functionName) {
      switch (functionName) {
        case "loadTest1":
          this.loading = true;
          // 模拟延迟请求
          setTimeout(() => {
            console.log("加载区块1");
            this.loading = false;
          }, 1000);
          break;
        case "loadTest2":
          this.loading = true;
          // 模拟延迟请求
          setTimeout(() => {
            console.log("加载区块2");
            this.loading = false;
          }, 1000);
          break;
        case "loadTest3":
          this.loading = true;
          // 模拟延迟请求
          setTimeout(() => {
            console.log("加载区块3");
            this.loading = false;
          }, 1000);
          break;
        case "loadTest4":
          this.loading = true;
          // 模拟延迟请求
          setTimeout(() => {
            console.log("加载区块4");
            this.loading = false;
          }, 1000);
          break;
        case "loadTest5":
          this.loading = true;
          // 模拟延迟请求
          setTimeout(() => {
            console.log("加载区块5");
            this.loading = false;
          }, 1000);
          break;
        case "loadTest6":
          this.loading = true;
          // 模拟延迟请求
          setTimeout(() => {
            console.log("加载区块6");
            this.loading = false;
          }, 1000);
          break;
      }
    },
  },
};
</script>


<style scoped>
.page {
  width: 100vw;
  height: 100vh;
  overflow-y: auto;
  display: flex;
  flex-wrap: wrap;
  /* justify-content: center;
  align-items: center; */
}
.item {
  width: 100vw;
  height: 25vh;
  display: flex;
  justify-content: center;
  align-items: center;
}
.gray {
  background-color: #d5d1d1;
}
.white {
  background-color: white;
}
.loading {
  width: 80px;
  height: 100px;
  background: rgba(0, 0, 255, 0.664);
  display: inline-block;
}
</style>



需要注意 getBoundingClientRect()这个方法,正是通过这个方法获取元素位置,从而判断是否出现在可视区域

到此这篇关于基于vue实现页面滚动加载的示例详解的文章就介绍到这了,更多相关vue页面滚动加载内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Vue声明式导航与编程式导航示例分析讲解

    Vue声明式导航与编程式导航示例分析讲解

    这篇文章主要介绍了Vue中声明式导航与编程式导航,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-11-11
  • vue webpack build资源相对路径的问题及解决方法

    vue webpack build资源相对路径的问题及解决方法

    这篇文章主要介绍了vue webpack build资源相对路径的问题,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06
  • vue使用watch 观察路由变化,重新获取内容

    vue使用watch 观察路由变化,重新获取内容

    本篇文章主要介绍了vue使用watch 观察路由变化,重新获取内容 ,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-03-03
  • Vue.js绑定HTML class数组语法错误的原因分析

    Vue.js绑定HTML class数组语法错误的原因分析

    Vue.js绑定HTML class数组语法错误有哪些原因导致的呢,该如何解决呢?下面小编给大家分享Vue.js绑定HTML class数组语法错误的原因分析,感兴趣的朋友一起看看吧
    2016-10-10
  • 安装node.js以及搭建vue项目过程中遇到的问题详解

    安装node.js以及搭建vue项目过程中遇到的问题详解

    为了让一些不太清楚搭建前端项目的小白,更快上手,下面这篇文章主要给大家介绍了关于安装node.js以及搭建vue项目过程中遇到问题的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • 使用vuex的state状态对象的5种方式

    使用vuex的state状态对象的5种方式

    本文给大家介绍了使用vuex的state状态对象的5种方式,给大家贴出了我的vuex的结构,感兴趣的朋友跟随脚本之家小编一起学习吧
    2018-04-04
  • Vue2项目配置@指向src路径方式

    Vue2项目配置@指向src路径方式

    这篇文章主要介绍了Vue2项目配置@指向src路径方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • vue项目出现ERESOLVE could not resolve问题及解决

    vue项目出现ERESOLVE could not resolve问题及解决

    这篇文章主要介绍了vue项目出现ERESOLVE could not resolve问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • Vue+Vux实现登录功能

    Vue+Vux实现登录功能

    这篇文章主要介绍了Vue+Vux实现登录功能,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08
  • vue2项目解决IE、360浏览器兼容问题的办法

    vue2项目解决IE、360浏览器兼容问题的办法

    虽然已经摈弃ie的使用,但是在现阶段还是在某些场景下需要用到ie,这篇文章主要给大家介绍了关于vue2项目解决IE、360浏览器兼容问题的办法,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-09-09

最新评论