Rumah hujung hadapan web tutorial js 在vue2中如何实现上拉加载功能

在vue2中如何实现上拉加载功能

Jun 23, 2018 pm 06:02 PM
vue vue2 pemuatan tarik naik

这篇文章主要为大家详细介绍了基于vue2实现上拉加载功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了vue2实现上拉加载展示的具体代码,供大家参考,具体内容如下

因为我们项目中,还用了swiper。很多都是滑动切换的,但是又得上拉加载,所以导致,很多UI框架,我们用了,都有不同的bug出现,没办法,最后写了一个。代码如下(这个因为很多地方会用,所以建议放在components/common下面):

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

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

<script>
  export default {
    name: &#39;loadmore&#39;,
    props: {
      maxDistance: {
        type: Number,
        default: 0
      },
      autoFill: {
        type: Boolean,
        default: true
      },
      distanceIndex: {
        type: Number,
        default: 2
      },
      bottomPullText: {
        type: String,
        default: &#39;上拉刷新&#39;
      },
      bottomDropText: {
        type: String,
        default: &#39;释放更新&#39;
      },
      bottomLoadingText: {
        type: String,
        default: &#39;加载中...&#39;
      },
      bottomDistance: {
        type: Number,
        default: 70
      },
      bottomMethod: {
        type: Function
      },
      bottomAllLoaded: {
        type: Boolean,
        default: false
      },
    },
    data() {
      return {
        // 最下面出现的p的位移
        translate: 0,
        // 选择滚动事件的监听对象
        scrollEventTarget: null,
        containerFilled: false,
        bottomText: &#39;&#39;,
        // class类名
        bottomDropped: false,
        // 获取监听滚动元素的scrollTop
        bottomReached: false,
        // 滑动的方向  down---向下互动;up---向上滑动
        direction: &#39;&#39;,
        startY: 0,
        startScrollTop: 0,
        // 实时的clientY位置
        currentY: 0,
        topStatus: &#39;&#39;,
        // 上拉加载的状态  &#39;&#39;   pull: 上拉中
        bottomStatus: &#39;&#39;,
      };
    },
    watch: {
      // 改变当前加载在状态
      bottomStatus(val) {
        this.$emit(&#39;bottom-status-change&#39;, val);
        switch (val) {
          case &#39;pull&#39;:
            this.bottomText = this.bottomPullText;
            break;
          case &#39;drop&#39;:
            this.bottomText = this.bottomDropText;
            break;
          case &#39;loading&#39;:
            this.bottomText = this.bottomLoadingText;
            break;
        }
      }
    },
    methods: {
      onBottomLoaded() {
        this.bottomStatus = &#39;pull&#39;;
        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 !== &#39;HTML&#39; &&
        currentNode.tagName !== &#39;BODY&#39; && currentNode.nodeType === 1) {
          let overflowY = document.defaultView.getComputedStyle(currentNode).overflowY;
          if (overflowY === &#39;scroll&#39; || overflowY === &#39;auto&#39;) {
            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(&#39;touchstart&#39;, this.handleTouchStart);
        this.$el.addEventListener(&#39;touchmove&#39;, this.handleTouchMove);
        this.$el.addEventListener(&#39;touchend&#39;, this.handleTouchEnd);
      },
      init() {
        this.bottomStatus = &#39;pull&#39;;
        // 选择滚动事件的监听对象
        this.scrollEventTarget = this.getScrollEventTarget(this.$el);
        if (typeof this.bottomMethod === &#39;function&#39;) {
          // autoFill 属性的实现  注释
          this.fillContainer();
          // 绑定滑动事件
          this.bindTouchEvents();
        }
      },
      // autoFill 属性的实现  注释
      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 = &#39;loading&#39;;
            this.bottomMethod();
          }
        });
        }
      },
      // 获取监听滚动元素的scrollTop
      checkBottomReached() {
        if (this.scrollEventTarget === window) {
          return document.body.scrollTop + document.documentElement.clientHeight >= document.body.scrollHeight;
        } else {
          // getBoundingClientRect用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置。 right是指元素右边界距窗口最左边的距离,bottom是指元素下边界距窗口最上面的距离。
          return this.$el.getBoundingClientRect().bottom <= this.scrollEventTarget.getBoundingClientRect().bottom + 1;
        }
      },
      // ontouchstart 事件
      handleTouchStart(event) {
        // 获取起点的y坐标
        this.startY = event.touches[0].clientY;
        this.startScrollTop = this.getScrollTop(this.scrollEventTarget);
        this.bottomReached = false;
        if (this.bottomStatus !== &#39;loading&#39;) {
          this.bottomStatus = &#39;pull&#39;;
          this.bottomDropped = false;
        }
      },
      // ontouchmove事件
      handleTouchMove(event) {
        if (this.startY < this.$el.getBoundingClientRect().top && this.startY > this.$el.getBoundingClientRect().bottom) {
          // 没有在需要滚动的范围内滚动,不再监听scroll
          return;
        }
        // 实时的clientY位置
        this.currentY = event.touches[0].clientY;
        // distance 移动位置和开始位置的差值    distanceIndex---
        let distance = (this.currentY - this.startY) / this.distanceIndex;
        // 根据 distance 判断滑动的方向 并赋予变量  direction down---向下互动;up---向上滑动
        this.direction = distance > 0 ? &#39;down&#39; : &#39;up&#39;;
        if (this.direction === &#39;up&#39;) {
          // 获取监听滚动元素的scrollTop
          this.bottomReached = this.bottomReached || this.checkBottomReached();
        }
        if (typeof this.bottomMethod === &#39;function&#39; && this.direction === &#39;up&#39; &&
            this.bottomReached && this.bottomStatus !== &#39;loading&#39; && !this.bottomAllLoaded) {
          // 有加载函数,是向上拉,有滚动距离,不是正在加载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 ? &#39;drop&#39; : &#39;pull&#39;;
        }
      },
      // ontouchend事件
      handleTouchEnd() {
        if (this.direction === &#39;up&#39; && this.bottomReached && this.translate < 0) {
          this.bottomDropped = true;
          this.bottomReached = false;
          if (this.bottomStatus === &#39;drop&#39;) {
            this.translate = &#39;-50&#39;;
            this.bottomStatus = &#39;loading&#39;;
            this.bottomMethod();
          } else {
            this.translate = &#39;0&#39;;
            this.bottomStatus = &#39;pull&#39;;
          }
        }
        this.direction = &#39;&#39;;
      }
    },
    mounted() {
      this.init();
    }
  };
</script>
Salin selepas log masuk

然后哪个页面需要,在哪个页面导入即可:import LoadMore from './../common/loadmore.vue';在需要引入他的页面写法如下:

<template>
 <section class="finan">
  <!-- 上拉加载更多 -->
  <load-more
  :bottom-method="loadBottom"
  :bottom-all-loaded="allLoaded"
  :bottomPullText=&#39;bottomText&#39;
  :auto-fill="false"
  @bottom-status-change="handleBottomChange"
  ref="loadmore">
    <p>
  这里写你需要的另外的模块
    </p>
    <p v-show="loading" slot="bottom" class="loading"> 这个p是为让上拉加载的时候显示一张加载的gif图
     <img src="./../../assets/main/uploading.gif">
    </p>
  </load-more>
 </section>
</template>
Salin selepas log masuk

然后在此页面的data里和methods设置如下:

  export default {
    name: &#39;FinancialGroup&#39;,
    props:{
 
    },
    data () {
      return {
        // 上拉加载数据
        scrollHeight: 0,
        scrollTop: 0,
        containerHeight: 0,
        loading: false,
        allLoaded: false,
        bottomText: &#39;上拉加载更多...&#39;,
        bottomStatus: &#39;&#39;,
        pageNo: 1,
        totalCount: &#39;&#39;,
      }
    },
    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;  // 每次更迭加载的页数
      if (this.pageNo == this.totalGetCount) {
        // 当allLoaded = true时上拉加载停止
        this.loading = false;
        this.allLoaded = true;
      }
      api.commonApi(后台接口,请求参数) 这个api是封装的axios有不懂的可以看vue2+vuex+axios那篇文章
          .then(res => {
        setTimeout(() => {
      要使用的后台返回的数据写在setTimeout里面
         this.$nextTick(() => {
          this.loading = false;
        })
      }, 1000)
     });
    },
    handleBottomChange(status) {
      this.bottomStatus = status;
    },
  }
Salin selepas log masuk

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

使用JavaScript如何实现寄生组合式继承

在JS中如何实现非首屏图片延迟加载

在jQuery中有关于库的引用方法有哪些

在js中如何生成word图片

Atas ialah kandungan terperinci 在vue2中如何实现上拉加载功能. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Cara menambah fungsi ke butang untuk vue Cara menambah fungsi ke butang untuk vue Apr 08, 2025 am 08:51 AM

Anda boleh menambah fungsi ke butang VUE dengan mengikat butang dalam templat HTML ke kaedah. Tentukan kaedah dan tulis logik fungsi dalam contoh Vue.

Cara menggunakan bootstrap di vue Cara menggunakan bootstrap di vue Apr 07, 2025 pm 11:33 PM

Menggunakan bootstrap dalam vue.js dibahagikan kepada lima langkah: Pasang bootstrap. Import bootstrap di main.js. Gunakan komponen bootstrap secara langsung dalam templat. Pilihan: Gaya tersuai. Pilihan: Gunakan pemalam.

Cara Menggunakan Watch di Vue Cara Menggunakan Watch di Vue Apr 07, 2025 pm 11:36 PM

Pilihan Watch di Vue.js membolehkan pemaju mendengar perubahan dalam data tertentu. Apabila data berubah, tontonkan mencetuskan fungsi panggil balik untuk melakukan paparan kemas kini atau tugas lain. Pilihan konfigurasinya termasuk segera, yang menentukan sama ada untuk melaksanakan panggilan balik dengan serta -merta, dan mendalam, yang menentukan sama ada untuk mendengarkan secara rekursif terhadap objek atau tatasusunan.

Cara merujuk fail js dengan vue.js Cara merujuk fail js dengan vue.js Apr 07, 2025 pm 11:27 PM

Terdapat tiga cara untuk merujuk kepada fail JS dalam vue.js: Secara langsung tentukan jalan menggunakan & lt; skrip & gt; tag ;; import dinamik menggunakan cangkuk kitaran hayat yang dipasang (); dan mengimport melalui Perpustakaan Pengurusan Negeri VUEX.

Apakah yang dimaksudkan dengan pembangunan Vue Multi-Page? Apakah yang dimaksudkan dengan pembangunan Vue Multi-Page? Apr 07, 2025 pm 11:57 PM

Pembangunan pelbagai halaman Vue adalah cara untuk membina aplikasi menggunakan rangka kerja VUE.JS, di mana permohonan dibahagikan kepada halaman berasingan: Penyelenggaraan kod: Memisahkan aplikasi ke dalam beberapa halaman boleh menjadikan kod lebih mudah untuk dikendalikan dan diselenggarakan. Modularity: Setiap halaman boleh digunakan sebagai modul yang berasingan untuk penggunaan semula dan penggantian mudah. Routing mudah: Navigasi antara halaman boleh diuruskan melalui konfigurasi penghalaan mudah. Pengoptimuman SEO: Setiap halaman mempunyai URL sendiri, yang membantu SEO.

Cara kembali ke halaman sebelumnya oleh Vue Cara kembali ke halaman sebelumnya oleh Vue Apr 07, 2025 pm 11:30 PM

Vue.js mempunyai empat kaedah untuk kembali ke halaman sebelumnya: $ router.go (-1) $ router.back () menggunakan & lt; router-link to = & quot;/& quot; Komponen Window.History.Back (), dan pemilihan kaedah bergantung pada tempat kejadian.

Cara Menanyakan Versi Vue Cara Menanyakan Versi Vue Apr 07, 2025 pm 11:24 PM

Anda boleh menanyakan versi VUE dengan menggunakan Vue Devtools untuk melihat tab VUE dalam konsol penyemak imbas. Gunakan NPM untuk menjalankan arahan "NPM LIST -G VUE". Cari item VUE dalam objek "Dependencies" fail Package.json. Untuk projek Vue CLI, jalankan perintah "Vue -version". Semak maklumat versi di & lt; skrip & gt; Tag dalam fail HTML yang merujuk kepada fail VUE.

Cara Menggunakan Fungsi Memintas Vue Cara Menggunakan Fungsi Memintas Vue Apr 08, 2025 am 06:51 AM

Pemintasan fungsi dalam VUE adalah teknik yang digunakan untuk mengehadkan bilangan kali fungsi dipanggil dalam tempoh masa yang ditentukan dan mencegah masalah prestasi. Kaedah pelaksanaan adalah: mengimport perpustakaan lodash: import {debounce} dari 'lodash'; Gunakan fungsi debounce untuk membuat fungsi memintas: const debouncedfunction = debounce (() = & gt; { / logical /}, 500); Panggil fungsi Intercept, dan fungsi kawalan dipanggil paling banyak sekali dalam 500 milisaat.

See all articles