背景

  之前写过一篇《纯JS实现加载更多(VUE框架)》,它的逻辑思路比较清晰易懂,而今天看了一天公司项目的部分功能代码,发现同事们写的加载更多的功能更加的有趣,而且易于封装到一个组件当中,便于日后的重用。

 

 

思路

  同样是检测滚动,然后计算可滑动高度、滑动高度、屏幕高度然后计算什么时候可以向后台请求数据,加载数据。而不同的是这次结合了vue.js中的全局API之Vue.directive(自定义指令,关于它的知识,官网上面已经写得很清晰了),创建一个自定义指令,类似于v-show这样的指令,然后直接挂到DOM那里,再写上参数,通过directive对应的钩子函数(注意,这里的全局api也有自己相对应的钩子函数哟),来为绑定了该自定义指令的DOM节点添加滑动事件。

 

 

动手吧

  首先使用全局api  Vue.directive自定义自己的指令,取名为‘loadMore’,然后写下钩子函数inserted()、unbind()。

  其中onScroll()函数是自定义方法,作用是实现滚动加载更多的功能。

  inseted()钩子函数的作用是当被绑定元素插入父节点时,调用此钩子函数,为被绑定元素绑定监听滑动scroll的时间方法,一旦被绑定元素被监听到滑动,调用onScroll()函数实现加载更多。

  unbind()钩子函数的作用是当指令与元素解绑时,调用该钩子(即退出页面或者程序时调用)

  程序如下所示:

import Vue from \'vue\';
Vue.directive(\'loadMore\', { inserted(ele, data) { ele.addEventListener(\'scroll\', data.def.onScroll.bind(null, data)) console.log(data) console.log(\'inserted钩子函数被触发咯~~~\') }, unbind(ele, data) { ele.removeEventListener(\'scroll\', data).def.onScroll.bind(null, data) console.log(\'解绑时调用!!!!\') }, onScroll(data, event) { let target = event.target; let loadMoreConfig = data.value; let screenHeight = target.offsetHeight; let scrollTop = target.scrollTop; let totalHeight = target.scrollHeight; if (!loadMoreConfig.loading && totalHeight > screenHeight && totalHeight - scrollTop - screenHeight < loadMoreConfig.scrollBottomOffset) { loadMoreConfig.onScrollBottom(); loadMoreConfig.loading = true; } }, });

上面这段程序写在<script></script>里面,写在export default外面。

 

 

使用自定义指令

  因为上面定义了一个指令,叫loadMore, 像v-show、v-if一样挂载DOM中,然后传需要的参数就可以了,如下

<pull-refresh :next="reloadNewKnowLedgeDataList" class="knowledge-list-container" v-load-more="newPageInfo.loadMoreConfig">……

 

  上面传的参数是newPageInfo.loadMoreConfig,在data()里面,它是这样的

data() {
    return {
      newPageInfo: {
        isLoadedData: false,
        pageNo: 1,  // 第一页
        pageSize: 15, // 每一次加载的最大页数
        dataList: [],
        loadMoreConfig: {
          onScrollBottom: this.onScrollBottomForNewPage,  //调用加载的方法
          scrollBottomOffset: 20,  //距离底部门槛阈值
          loading: false //是否加载
        }
      }
}

  看到了吗,因为之前在全局api directive里面自己定义的监听滑动后触发函数onScroll(),一旦触发它,函数就会调用this.onScrollBottomForNewPage()方法来加载数据

 

接着上面按逻辑执行

 

onScrollBottomForNewPage() {
      this.newPageInfo.pageNo += 1;
      this.queryNewKnowLedgeDataList();
},

queryNewKnowLedgeDataList(callback) {
      this.loading(true);
      this.queryKnowLedgeDataMethod(\'new\').then((res) => {
        if (callback && typeof callback === \'function\') {
          callback();
        }
        this.newPageInfo.isLoadedData = true;
        this.loading(false);
        this.processNewKnowLedgeData(res);
      }, (error) => {
        if (callback && typeof callback === \'function\') {
          callback();
        }
        this.loading(false);
        this.newPageInfo.loadMoreConfig.loading = true;
        this.newPageInfo.isLoadedData = true;
        if (error !== null) {
          this.$vux.toast.show({ text: \'数据加载失败\', type: \'text\' });
        }
      });
},

queryKnowLedgeDataMethod(type) {
      let params;
      if (type === \'new\') {
        params = {
          \'pageNo\': this.newPageInfo.pageNo,
          \'pageSize\': this.newPageInfo.pageSize,
          \'findType\': 0
        };
      } else {
        params = {
          \'pageNo\': this.hotPageInfo.pageNo,
          \'pageSize\': this.hotPageInfo.pageSize,
          \'findType\': 1
        };
      }
      return this.$http.get(\'rule/findRuleNewOrHotList\', { \'params\': params });
},

processNewKnowLedgeData(res) {
      if (!res) {
        return;
      }
      if (res.data && res.data.length > 0) {
        if (this.newPageInfo.pageNo === 1) {
          this.newPageInfo.dataList = res.data;
        } else {
          this.newPageInfo.dataList = this.newPageInfo.dataList.concat(res.data);
        }
        this.newPageInfo.loadMoreConfig.loading = false;
      } else {
        this.newPageInfo.loadMoreConfig.loading = true;
        if (this.newPageInfo.pageNo === 1) {
          this.newPageInfo.dataList = [];
        } else {
          this.$vux.toast.show({ text: \'没有更多\', type: \'text\' });
        }
      }
},

 

  

 

版权声明:本文为pengshengguang原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/pengshengguang/p/8038758.html