欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

手寫vue無限滾動指令的詳細過程

 更新時間:2022年09月07日 10:44:13   作者:ginp  
今天在移動端項目中遇見一個需求,需要數據無限滾動,所以下面這篇文章主要給大家介紹了關于手寫vue無限滾動指令的詳細過程,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下

概述

日常的開發(fā)當中,為了處理大量數據的情況,一般前端會采用分頁展示,可以通過分頁插件進行數據的按需分頁請求展示,另一種解決大量數據的渲染的方式就是無限滾動,在移動端比較常見,也就是我們常見的滾動到底部加載更多數據,一般web端用下拉加載更多場景不是很多,但是也還是有,比如京東和淘寶的web官方,就用到了無限滾動,通過滾動到底部,然后加載更多數據??傊?,無限滾動和分頁插件都是為了解決大數據展示的問題,現在介紹下vue中通過自定義指令實現無限滾動。

最終效果

實現原理

在開始敲代碼之前,先講一下無限滾動的原理,首選我們需要之前的,怎么才算滾動到底部,然后我們才能去執(zhí)行加載更多的函數。

關于高度計算的幾個方法

clientHeigt

  • 這兩個屬性用于獲取元素塊可視區(qū)的寬高,該屬性包括內邊距 padding,但不包括邊框 border、外邊距 margin 和垂直滾動條

scrollHeight

  • 一個元素內容高度的度量,包括由于溢出導致的視圖中不可見內容,也就是一個元素寬的實際高度,包含被滾動條卷走的部分。具體看下圖:

scrollTop

  • 滾動條卷走的高度。,參考下圖:

綜上

得出滾動條到達底部的計算公式為:clientHeight + scrollTop == scrollHeight,知道這個之后,我們寫邏輯就容易多了,只需要在滾動條到達底部的時候,重新取獲取數據就可以了。

目錄結構

App.vue

無限滾動首選需要一個固定高度的盒子然后設置 style="overflow: auto" 然后可以根據需要加上滾動結束的限制,比如loading等

<template>
  <div id="app">
  //外層包裹盒子
      <div
        class="infinite-list"
        v-infinite-scroll.loading.complated.immediate="load"
        style="overflow: auto"
        ref="infiniteList"
      >
        <ul>
          <li v-for="i in count" class="infinite-list-item">{{ i }}</li>
        </ul>
        //加載中
        <p v-if="loading && !complated" class="text">加載中...</p>
        //結束了
        <p v-if="complated" class="text">沒有更多了</p>
      </div>
    </div>
  </div>
</template>

<script>
import Velocity from "velocity-animate";
import { DatePicker } from "./components/DatePicker/index";
export default {
  name: "App",
  components: {
    DatePicker,
  },
  data() {
      count: 1,
      loading: false,
      complated: false,
    };
  },
  methods: {
  //滾動到底部的處理邏輯
    load() {
      // 以下是定時器模擬異步數據請求,可根據自己的需求進行變更
      this.loading = true;
      setTimeout(() => {
        if (this.count >= 15) {
          this.complated = true;
          return;
        }
        this.count += 3;
        this.loading = false;
      }, 1000);
    },
  },
};
</script>

<style lang="less">
#app {
  .infinite-list {
    height: 300px;
    width: 500px;
    border: 1px solid red;
    li {
      height: 50px;
      background: #e8f3fe;
      margin: 10px;
      color: #7dbcfc;
      text-align: center;
      line-height: 50px;
    }
    .text {
      color: green;
      text-align: center;
      line-height: 50px;
    }
  }
}
</style>

./components/v-infinite-scroll/index.js

import { checkArriveBottom } from "./utils";
export default {
  install(Vue) {
    Vue.directive("infinite-scroll", {
      // 指令在插入的時候會執(zhí)行一次
      inserted: function (el, binding, vnode) {
        const fn = binding.value;
        const context = vnode.context;
        let timer = null;
        // 指令的值必須是一個函數,我們好執(zhí)行回調
        if (typeof fn != "function") {
          throw new Error("指令value必須為函數");
        }
        // 事件處理函數
        function handleScroll() {
          // 判斷滾動條到達底部了,才開始執(zhí)行回調
          if (checkArriveBottom(el)) {
            // 執(zhí)行回調的時候,要把this指向組件實例
            fn.bind(context)();
          }
        }
        // 將滾動處理函數掛載到對應組件實例上面,便于組件更新的時候,對設置了loading和complate屬性進行移除事件綁定
        context.handleScroll = handleScroll;
        // 如果設置有immediate說明立即執(zhí)行,則立即執(zhí)行回調,直到將內容撐滿內容區(qū)
        if (binding?.modifiers?.immediate) {
          timer = setInterval(() => {
            // 子元素的總高度大于設置指令的父級包裹元素就表示填滿了可視區(qū),停止加載
            const childScrollHeight = el.firstElementChild.scrollHeight;
            if (childScrollHeight >= el.clientHeight) {
              return clearInterval(timer);
            }
            handleScroll();
          }, 1500);
        }
        // 綁定滾動處理函數
        el.addEventListener("scroll", context.handleScroll);
      },
      //   組件更新的時候,會不斷觸發(fā)(最明顯就是data中的響應式數據變化,會繼續(xù)執(zhí)行update方法)
      update(el, binding, vnode) {
        const context = vnode.context;
        // 如果加載中或者已經加載完了,就移除滾動事件
        if (
          (binding?.modifiers?.complated && context.complated) ||
          (binding?.modifiers?.loading && context.loading)
        ) {
          el.removeEventListener("scroll", context.handleScroll);
        } else {
          // 當loading和complate都是false的時候,表示可以繼續(xù)加載
          el.addEventListener("scroll", context.handleScroll);
        }
      },
    });
  },
};

./components/v-infinite-scroll/utils.js

/**
 * @Description 用于判斷滾動條是否到達底部
 * @param { Element }
 * @return { Boolean }
 **/
export function checkArriveBottom(el) {
  const clientHeight = el.clientHeight;
  const scrollTop = el.scrollTop;
  const scrollHeight = el.scrollHeight;
  //可以設置>=就行,這里也可以設置距離底部一定距離,自定義,不一定非要到達底部
  return clientHeight + scrollTop >= scrollHeight;
}

./components/v-infinite-scroll/main.js

import Vue from "vue";
import App from "./App.vue";
import vInfiniteScroll from "./components/v-infinite-scroll";
Vue.use(vInfiniteScroll);
Vue.use(myUi);
new Vue({
  render: (h) => h(App),
}).$mount("#app");

總結

完成上述指令,需要先閱讀官網自定義指令文檔,搞懂具體指令的一些鉤子函數的用途以及觸發(fā)時機,還有就是參數的意義,鏈接放這里cn.vuejs.org/v2/guide/cu…

到此這篇關于手寫vue無限滾動指令的文章就介紹到這了,更多相關vue無限滾動指令內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • vue使用$store.commit() undefined報錯的解決

    vue使用$store.commit() undefined報錯的解決

    這篇文章主要介紹了vue使用$store.commit() undefined報錯的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • VUE 實現動態(tài)給對象增加屬性,并觸發(fā)視圖更新操作示例

    VUE 實現動態(tài)給對象增加屬性,并觸發(fā)視圖更新操作示例

    這篇文章主要介紹了VUE 實現動態(tài)給對象增加屬性,并觸發(fā)視圖更新操作,涉及vue.js對象屬性動態(tài)操作及視圖更新相關實現技巧,需要的朋友可以參考下
    2019-11-11
  • 適用于 Vue 的播放器組件Vue-Video-Player操作

    適用于 Vue 的播放器組件Vue-Video-Player操作

    這篇文章主要介紹了適用于 Vue 的播放器組件Vue-Video-Player操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • Electron集成React和Vue流程方法講解

    Electron集成React和Vue流程方法講解

    Electron也可以快速地將你的網站打包成一個原生應用發(fā)布,下面這篇文章主要給大家介紹了關于Electron集成React和Vue的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-08-08
  • 淺談Vue數據響應思路之數組

    淺談Vue數據響應思路之數組

    這篇文章主要介紹了淺談Vue數據響應思路之數組,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • 利用Vite搭建Vue3+ElementUI-Plus項目的全過程

    利用Vite搭建Vue3+ElementUI-Plus項目的全過程

    vue3如今已經成為默認版本了,相信大多數公司已經全面擁抱vue3了,下面這篇文章主要給大家介紹了關于利用Vite搭建Vue3+ElementUI-Plus項目的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-07-07
  • vue+element創(chuàng)建動態(tài)的form表單及動態(tài)生成表格的行和列

    vue+element創(chuàng)建動態(tài)的form表單及動態(tài)生成表格的行和列

    這篇文章主要介紹了vue+element創(chuàng)建動態(tài)的form表單及動態(tài)生成表格的行和列 ,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-05-05
  • Vue數字輸入框組件使用方法詳解

    Vue數字輸入框組件使用方法詳解

    這篇文章主要為大家詳細介紹了Vue數字輸入框組件的使用方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • Vue3格式化Volar報錯的原因分析與解決

    Vue3格式化Volar報錯的原因分析與解決

    Volar 與vetur相同,volar是一個針對vue的vscode插件,下面這篇文章主要給大家介紹了關于Vue3格式化Volar報錯的原因分析與解決方法,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2022-06-06
  • Vue header組件開發(fā)詳解

    Vue header組件開發(fā)詳解

    本篇文章主要介紹了Vue header組件開發(fā)詳解,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01

最新評論