vue懒加载-任务队列

目录

一、vue-observe-visibility简介

二、问题描述

三、逻辑步骤

四、结语


一、vue-observe-visibility简介

vue-observe-visibility是vue的懒加载插件,他可以实现元素出现在视口可见范围之内,调用回调函数,执行一系列操作,还可以控制是否监听元素,是否只监听一次以及节流监听等,具体api以及安装方法,可以参照官方文档:安装 | vue-observe-visibility

二、问题描述

实现元素出现在可视范围内,依次向后台请求数据,数据回来之后依次加载图表。

如果单纯使用vue-observe-visibility插件,那么如果滚轮滑动的较快,可能一次性会有很多元素出现在可视范围内,这时会造成同时向后台发送请求的情况,如果服务器配置不高,可能会导致服务器崩溃(对,没错,我们公司的服务器就摇摇欲坠,经不起考验),那如何解同时发起请求的问题呢?

三、逻辑步骤

  1. 创建observeVisibily.js文件,定义ObserveVisible
  2. 定义数组queueList,用于存放方法队列
  3. 队列方法是否执行标识queunIsRun,防止滚轮滑动过快,短时间内大量调用执行队列方法
  4. 定义所监听元素对象isVisi,用于确定哪个对象出现在了可视范围内
  5. 初始化元素对象方法createIsvisi,用于创建所需对象格式
      // 获取初始element列表,用于标识元素是否可见,els参数为数组形式,传入元素唯一标识
      // [ 'el1', 'el2' ]
      createIsvisi(els) {
        els.forEach(item => {
          Vue.set(this.isVisi, item, {
            loading: false,
            observe: true
          })
        })
      }
  6. 向任务队列添加方法函数addQueue

      // 添加任务队列
      addQueue({ visi, func, params }) {
        this.queueList.push({
          visi,
          func,
          params,
        })
      }
  7. 执行任务队列函数doQueue,调用doQueue时,需先判断queunIsRun是否为true,如果为true,则证明正在执行任务队列,这时直接return。如果为false,则判断任务队列数组长度,如果不为0,那么弹出数组第一列,执行弹出的方法,结束之后递归调用自身,直至任务队列长度为0(注意,这里递归调用自身需要传入标识isSelf,用于与queunIsRun联合判断,当isSelftrue时,无论queunIsRun是什么状态,都需要执行自身 )

      // 执行任务队列
      async doQueue(isSelf) {
        if (!isSelf && this.queunIsRun) return
        this.queunIsRun = true;
        try {
          if (this.queueList.length) {
            const item = this.queueList.shift();
            await item.func(item.params);
            Vue.set(this.isVisi[item.visi], 'loading', false)
            await this.doQueue(true);
          } else {
            this.closeQueue()
          }
        } catch (err) {
          console.log(err);
          if (this.queueList.length) {
            this.doQueue(true);
          } else {
            this.clearQueue();
          }
        }
      }
  8. 关闭任务队列函数closeQueue

      // 关闭任务队列
      closeQueue() {
        this.queunIsRun = false;
        this.isSearchDisable = false;
      }
  9. 清空任务队列clearQueue,用于调用函数出错时,重置状态

      // 清空任务队列,关闭所有loading状态
      clearQueue() {
        this.closeQueue()
        this.queueList = []
        Object.keys(this.isVisi).forEach(
          item => Vue.set(this.isVisi[item], 'loading', false)
        );
      }
  10. 重置元素列表状态方法resetIsvisi

      // 重置element列表状态
      resetIsvisi() {
        Object.keys(this.isVisi).forEach(
          item => Vue.set(this.isVisi[item], 'observe', true)
        );
      }
  11. 元素进入可视范围内函数visiElement

  // 元素进入可见范围
  visiElement(el) {
    this.isSearchDisable = true;
    Vue.set(this.isVisi[el], 'loading', true)
    Vue.set(this.isVisi[el], 'observe', false)
  }

四、使用方法 

  1. 在所需文件中引入observeVisibily.js
    import { ObserveVisible } from "../utils/observeVisibily.js";
  2. 定义实例参数observeVisible
          // 需要懒加载的元素
          observeVisible: null,
          // 需要懒加载的元素
          isVisiList: [
            "el1",
            "el2",
            "el3"
          ],
  3. created方法中创建实例对象

    this.observeVisible = new ObserveVisible(this.isVisiList);
  4. 定义懒加载回调函数visibilityChanged

    visibilityChanged(element) {
      return async (isVisible) => {
        if (isVisible) {
          try {
            this.observeVisible.visiElement(element);
            switch (element) {
              case "el1":
                this.observeVisible.addQueue({
                  func: this.el1Func,
                  visi: "el1",
                  params: this.params,
                });
                break;
              case "el2":
                this.observeVisible.addQueue({
                  func: this.el2Func,
                  visi: "el2",
                  params: this.params,
                });
                break;
              case "el3":
                this.observeVisible.addQueue({
                  func: this.el3Func,
                  visi: "el3",
                  params: this.params,
                });
                break;
              default:
                break;
            }
            this.observeVisible.doQueue();
          } catch (err) {
            console.log("懒加载错误 =", err);
          }
        }
      };
    }
  5. 在所需元素上绑定方法,其中有用到 vue-observe-visibility 相关api,具体请查看官网

    <div
      v-loading="observeVisible.isVisi.el1.loading"
      v-observe-visibility="
                observeVisible.isVisi.el1.observe
                  ? { callback: visibilityChanged('el1'), once: true }
                  : false">
    </div>

四、结语

在工作中,经常能遇到各种需求,你觉得不合理的需求,可能为了适应当前环境而产生的, 不能改变需求,那么只能改变自己。如果有小伙伴需要完整代码,可以私信我,看到了会回,欢迎点赞收藏~

  • 17
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值