最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于vue2實(shí)現(xiàn)上拉加載功能

 更新時(shí)間:2017年11月28日 09:04:21   作者:趙海辛  
這篇文章主要為大家詳細(xì)介紹了基于vue2實(shí)現(xiàn)上拉加載功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了vue2實(shí)現(xiàn)上拉加載展示的具體代碼,供大家參考,具體內(nèi)容如下

因?yàn)槲覀冺?xiàng)目中,還用了swiper。很多都是滑動(dòng)切換的,但是又得上拉加載,所以導(dǎo)致,很多UI框架,我們用了,都有不同的bug出現(xiàn),沒辦法,最后寫了一個(gè)。代碼如下(這個(gè)因?yàn)楹芏嗟胤綍?huì)用,所以建議放在components/common下面):

<template>
  <div class="loadmore">
    <slot></slot>
    <slot name="bottom">
    </slot>
  </div>
</template>

<style>
  .loadmore{
    width:100%;
  }
</style>

<script>
  export default {
    name: 'loadmore',
    props: {
      maxDistance: {
        type: Number,
        default: 0
      },
      autoFill: {
        type: Boolean,
        default: true
      },
      distanceIndex: {
        type: Number,
        default: 2
      },
      bottomPullText: {
        type: String,
        default: '上拉刷新'
      },
      bottomDropText: {
        type: String,
        default: '釋放更新'
      },
      bottomLoadingText: {
        type: String,
        default: '加載中...'
      },
      bottomDistance: {
        type: Number,
        default: 70
      },
      bottomMethod: {
        type: Function
      },
      bottomAllLoaded: {
        type: Boolean,
        default: false
      },
    },
    data() {
      return {
        // 最下面出現(xiàn)的div的位移
        translate: 0,
        // 選擇滾動(dòng)事件的監(jiān)聽對(duì)象
        scrollEventTarget: null,
        containerFilled: false,
        bottomText: '',
        // class類名
        bottomDropped: false,
        // 獲取監(jiān)聽滾動(dòng)元素的scrollTop
        bottomReached: false,
        // 滑動(dòng)的方向  down---向下互動(dòng);up---向上滑動(dòng)
        direction: '',
        startY: 0,
        startScrollTop: 0,
        // 實(shí)時(shí)的clientY位置
        currentY: 0,
        topStatus: '',
        // 上拉加載的狀態(tài)  ''   pull: 上拉中
        bottomStatus: '',
      };
    },
    watch: {
      // 改變當(dāng)前加載在狀態(tài)
      bottomStatus(val) {
        this.$emit('bottom-status-change', val);
        switch (val) {
          case 'pull':
            this.bottomText = this.bottomPullText;
            break;
          case 'drop':
            this.bottomText = this.bottomDropText;
            break;
          case 'loading':
            this.bottomText = this.bottomLoadingText;
            break;
        }
      }
    },
    methods: {
      onBottomLoaded() {
        this.bottomStatus = 'pull';
        this.bottomDropped = false;
        this.$nextTick(() => {
          if (this.scrollEventTarget === window) {
          document.body.scrollTop += 50;
        } else {
          this.scrollEventTarget.scrollTop += 50;
        }
        this.translate = 0;
      });
        // 注釋
        if (!this.bottomAllLoaded && !this.containerFilled) {
          this.fillContainer();
        }
      },

      getScrollEventTarget(element) {
        let currentNode = element;
        while (currentNode && currentNode.tagName !== 'HTML' &&
        currentNode.tagName !== 'BODY' && currentNode.nodeType === 1) {
          let overflowY = document.defaultView.getComputedStyle(currentNode).overflowY;
          if (overflowY === 'scroll' || overflowY === 'auto') {
            return currentNode;
          }
          currentNode = currentNode.parentNode;
        }
        return window;
      },
      // 獲取scrollTop
      getScrollTop(element) {
        if (element === window) {
          return Math.max(window.pageYOffset || 0, document.documentElement.scrollTop);
        } else {
          return element.scrollTop;
        }
      },
      bindTouchEvents() {
        this.$el.addEventListener('touchstart', this.handleTouchStart);
        this.$el.addEventListener('touchmove', this.handleTouchMove);
        this.$el.addEventListener('touchend', this.handleTouchEnd);
      },
      init() {
        this.bottomStatus = 'pull';
        // 選擇滾動(dòng)事件的監(jiān)聽對(duì)象
        this.scrollEventTarget = this.getScrollEventTarget(this.$el);
        if (typeof this.bottomMethod === 'function') {
          // autoFill 屬性的實(shí)現(xiàn)  注釋
          this.fillContainer();
          // 綁定滑動(dòng)事件
          this.bindTouchEvents();
        }
      },
      // autoFill 屬性的實(shí)現(xiàn)  注釋
      fillContainer() {
        if (this.autoFill) {
          this.$nextTick(() => {
            if (this.scrollEventTarget === window) {
            this.containerFilled = this.$el.getBoundingClientRect().bottom >=
                document.documentElement.getBoundingClientRect().bottom;
          } else {
            this.containerFilled = this.$el.getBoundingClientRect().bottom >=
                this.scrollEventTarget.getBoundingClientRect().bottom;
          }
          if (!this.containerFilled) {
            this.bottomStatus = 'loading';
            this.bottomMethod();
          }
        });
        }
      },
      // 獲取監(jiān)聽滾動(dòng)元素的scrollTop
      checkBottomReached() {
        if (this.scrollEventTarget === window) {
          return document.body.scrollTop + document.documentElement.clientHeight >= document.body.scrollHeight;
        } else {
          // getBoundingClientRect用于獲得頁面中某個(gè)元素的左,上,右和下分別相對(duì)瀏覽器視窗的位置。 right是指元素右邊界距窗口最左邊的距離,bottom是指元素下邊界距窗口最上面的距離。
          return this.$el.getBoundingClientRect().bottom <= this.scrollEventTarget.getBoundingClientRect().bottom + 1;
        }
      },
      // ontouchstart 事件
      handleTouchStart(event) {
        // 獲取起點(diǎn)的y坐標(biāo)
        this.startY = event.touches[0].clientY;
        this.startScrollTop = this.getScrollTop(this.scrollEventTarget);
        this.bottomReached = false;
        if (this.bottomStatus !== 'loading') {
          this.bottomStatus = 'pull';
          this.bottomDropped = false;
        }
      },
      // ontouchmove事件
      handleTouchMove(event) {
        if (this.startY < this.$el.getBoundingClientRect().top && this.startY > this.$el.getBoundingClientRect().bottom) {
          // 沒有在需要滾動(dòng)的范圍內(nèi)滾動(dòng),不再監(jiān)聽scroll
          return;
        }
        // 實(shí)時(shí)的clientY位置
        this.currentY = event.touches[0].clientY;
        // distance 移動(dòng)位置和開始位置的差值    distanceIndex---
        let distance = (this.currentY - this.startY) / this.distanceIndex;
        // 根據(jù) distance 判斷滑動(dòng)的方向 并賦予變量  direction down---向下互動(dòng);up---向上滑動(dòng)
        this.direction = distance > 0 ? 'down' : 'up';
        if (this.direction === 'up') {
          // 獲取監(jiān)聽滾動(dòng)元素的scrollTop
          this.bottomReached = this.bottomReached || this.checkBottomReached();
        }
        if (typeof this.bottomMethod === 'function' && this.direction === 'up' &&
            this.bottomReached && this.bottomStatus !== 'loading' && !this.bottomAllLoaded) {
          // 有加載函數(shù),是向上拉,有滾動(dòng)距離,不是正在加載ajax,沒有加載到最后一頁
          event.preventDefault();
          event.stopPropagation();
          if (this.maxDistance > 0) {
            this.translate = Math.abs(distance) <= this.maxDistance
                ? this.getScrollTop(this.scrollEventTarget) - this.startScrollTop + distance : this.translate;
          } else {
            this.translate = this.getScrollTop(this.scrollEventTarget) - this.startScrollTop + distance;
          }
          if (this.translate > 0) {
            this.translate = 0;
          }
          this.bottomStatus = -this.translate >= this.bottomDistance ? 'drop' : 'pull';
        }
      },
      // ontouchend事件
      handleTouchEnd() {
        if (this.direction === 'up' && this.bottomReached && this.translate < 0) {
          this.bottomDropped = true;
          this.bottomReached = false;
          if (this.bottomStatus === 'drop') {
            this.translate = '-50';
            this.bottomStatus = 'loading';
            this.bottomMethod();
          } else {
            this.translate = '0';
            this.bottomStatus = 'pull';
          }
        }
        this.direction = '';
      }
    },
    mounted() {
      this.init();
    }
  };
</script>

然后哪個(gè)頁面需要,在哪個(gè)頁面導(dǎo)入即可:import LoadMore from './../common/loadmore.vue';在需要引入他的頁面寫法如下:

<template>
 <section class="finan">
  <!-- 上拉加載更多 -->
  <load-more
  :bottom-method="loadBottom"
  :bottom-all-loaded="allLoaded"
  :bottomPullText='bottomText'
  :auto-fill="false"
  @bottom-status-change="handleBottomChange"
  ref="loadmore">
    <div>
  這里寫你需要的另外的模塊
    </div>
    <div v-show="loading" slot="bottom" class="loading"> 這個(gè)div是為讓上拉加載的時(shí)候顯示一張加載的gif圖
     <img src="./../../assets/main/uploading.gif">
    </div>
  </load-more>
 </section>
</template>

然后在此頁面的data里和methods設(shè)置如下:

  export default {
    name: 'FinancialGroup',
    props:{
 
    },
    data () {
      return {
        // 上拉加載數(shù)據(jù)
        scrollHeight: 0,
        scrollTop: 0,
        containerHeight: 0,
        loading: false,
        allLoaded: false,
        bottomText: '上拉加載更多...',
        bottomStatus: '',
        pageNo: 1,
        totalCount: '',
      }
    },
    methods: {
    /* 下拉加載 */
    _scroll: function(ev) {
      ev = ev || event;
      this.scrollHeight = this.$refs.innerScroll.scrollHeight;
      this.scrollTop = this.$refs.innerScroll.scrollTop;
      this.containerHeight = this.$refs.innerScroll.offsetHeight;
    },
    loadBottom: function() {
      this.loading = true;
      this.pageNo += 1;  // 每次更迭加載的頁數(shù)
      if (this.pageNo == this.totalGetCount) {
        // 當(dāng)allLoaded = true時(shí)上拉加載停止
        this.loading = false;
        this.allLoaded = true;
      }
      api.commonApi(后臺(tái)接口,請(qǐng)求參數(shù)) 這個(gè)api是封裝的axios有不懂的可以看vue2+vuex+axios那篇文章
          .then(res => {
        setTimeout(() => {
      要使用的后臺(tái)返回的數(shù)據(jù)寫在setTimeout里面
         this.$nextTick(() => {
          this.loading = false;
        })
      }, 1000)
     });
    },
    handleBottomChange(status) {
      this.bottomStatus = status;
    },
  }

這樣就完成了。

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • vue3中封裝axios請(qǐng)求最新實(shí)現(xiàn)步驟

    vue3中封裝axios請(qǐng)求最新實(shí)現(xiàn)步驟

    這篇文章主要給大家介紹了關(guān)于vue3中封裝axios請(qǐng)求的最新實(shí)現(xiàn)步驟,在Vue 3中可以通過封裝axios來實(shí)現(xiàn)接口的統(tǒng)一管理和調(diào)用,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-04-04
  • vue中使用mixins/extends傳入?yún)?shù)的方式

    vue中使用mixins/extends傳入?yún)?shù)的方式

    這篇文章主要介紹了vue中使用mixins/extends傳入?yún)?shù)的方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Vue動(dòng)態(tài)生成表格的行和列

    Vue動(dòng)態(tài)生成表格的行和列

    這篇文章主要為大家詳細(xì)介紹了Vue動(dòng)態(tài)生成表格的行和列,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • Element el-row el-col 布局組件詳解

    Element el-row el-col 布局組件詳解

    這篇文章主要介紹了Element el-row el-col 布局組件使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • vue中v-bind和v-model的區(qū)別詳解

    vue中v-bind和v-model的區(qū)別詳解

    v-bind和v-model是Vue.js中的兩個(gè)常用指令,它們?cè)诠δ芎陀猛旧嫌幸恍﹨^(qū)別,接下來小編就給大家具有講講vue中v-bind和v-model區(qū)別,感興趣的同學(xué)跟著小編一起來看看吧
    2023-08-08
  • ant-design-vue按鈕樣式擴(kuò)展方法詳解

    ant-design-vue按鈕樣式擴(kuò)展方法詳解

    這篇文章主要為大家介紹了ant-design-vue按鈕樣式擴(kuò)展方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • Vue如何根據(jù)角色獲取菜單動(dòng)態(tài)添加路由

    Vue如何根據(jù)角色獲取菜單動(dòng)態(tài)添加路由

    這篇文章主要介紹了Vue如何根據(jù)角色獲取菜單動(dòng)態(tài)添加路由,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-01-01
  • Vue子組件如何修改父組件數(shù)據(jù)的方法及注意事項(xiàng)

    Vue子組件如何修改父組件數(shù)據(jù)的方法及注意事項(xiàng)

    這篇文章主要介紹了Vue子組件如何修改父組件數(shù)據(jù)的方法及注意事項(xiàng),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • 實(shí)現(xiàn)shallowReadonly和isProxy功能示例詳解

    實(shí)現(xiàn)shallowReadonly和isProxy功能示例詳解

    這篇文章主要為大家介紹了實(shí)現(xiàn)shallowReadonly和isProxy功能示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • vue自定義指令之面板拖拽的實(shí)現(xiàn)

    vue自定義指令之面板拖拽的實(shí)現(xiàn)

    這篇文章主要介紹了vue自定義指令之面板拖拽的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04

最新評(píng)論

新源县| 杭锦后旗| 太仓市| 萍乡市| 六盘水市| 安顺市| 石景山区| 兰西县| 定州市| 景德镇市| 古田县| 克什克腾旗| 玉林市| 广安市| 白水县| 延川县| 平潭县| 类乌齐县| 宣恩县| 巴东县| 武邑县| 安国市| 内乡县| 灵璧县| 宝坻区| 阿勒泰市| 嫩江县| 搜索| 商洛市| 杭州市| 荔浦县| 徐汇区| 上蔡县| 盐城市| 石河子市| 界首市| 仁化县| 定襄县| 桦川县| 松江区| 新蔡县|