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

手寫vue無(wú)限滾動(dòng)指令的詳細(xì)過(guò)程

 更新時(shí)間:2022年09月07日 10:44:13   作者:ginp  
今天在移動(dòng)端項(xiàng)目中遇見(jiàn)一個(gè)需求,需要數(shù)據(jù)無(wú)限滾動(dòng),所以下面這篇文章主要給大家介紹了關(guān)于手寫vue無(wú)限滾動(dòng)指令的詳細(xì)過(guò)程,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

概述

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

最終效果

實(shí)現(xiàn)原理

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

關(guān)于高度計(jì)算的幾個(gè)方法

clientHeigt

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

scrollHeight

  • 一個(gè)元素內(nèi)容高度的度量,包括由于溢出導(dǎo)致的視圖中不可見(jiàn)內(nèi)容,也就是一個(gè)元素寬的實(shí)際高度,包含被滾動(dòng)條卷走的部分。具體看下圖:

scrollTop

  • 滾動(dòng)條卷走的高度。,參考下圖:

綜上

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

目錄結(jié)構(gòu)

App.vue

無(wú)限滾動(dòng)首選需要一個(gè)固定高度的盒子然后設(shè)置 style="overflow: auto" 然后可以根據(jù)需要加上滾動(dòng)結(jié)束的限制,比如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>
        //結(jié)束了
        <p v-if="complated" class="text">沒(méi)有更多了</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: {
  //滾動(dòng)到底部的處理邏輯
    load() {
      // 以下是定時(shí)器模擬異步數(shù)據(jù)請(qǐng)求,可根據(jù)自己的需求進(jìn)行變更
      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", {
      // 指令在插入的時(shí)候會(huì)執(zhí)行一次
      inserted: function (el, binding, vnode) {
        const fn = binding.value;
        const context = vnode.context;
        let timer = null;
        // 指令的值必須是一個(gè)函數(shù),我們好執(zhí)行回調(diào)
        if (typeof fn != "function") {
          throw new Error("指令value必須為函數(shù)");
        }
        // 事件處理函數(shù)
        function handleScroll() {
          // 判斷滾動(dòng)條到達(dá)底部了,才開始執(zhí)行回調(diào)
          if (checkArriveBottom(el)) {
            // 執(zhí)行回調(diào)的時(shí)候,要把this指向組件實(shí)例
            fn.bind(context)();
          }
        }
        // 將滾動(dòng)處理函數(shù)掛載到對(duì)應(yīng)組件實(shí)例上面,便于組件更新的時(shí)候,對(duì)設(shè)置了loading和complate屬性進(jìn)行移除事件綁定
        context.handleScroll = handleScroll;
        // 如果設(shè)置有immediate說(shuō)明立即執(zhí)行,則立即執(zhí)行回調(diào),直到將內(nèi)容撐滿內(nèi)容區(qū)
        if (binding?.modifiers?.immediate) {
          timer = setInterval(() => {
            // 子元素的總高度大于設(shè)置指令的父級(jí)包裹元素就表示填滿了可視區(qū),停止加載
            const childScrollHeight = el.firstElementChild.scrollHeight;
            if (childScrollHeight >= el.clientHeight) {
              return clearInterval(timer);
            }
            handleScroll();
          }, 1500);
        }
        // 綁定滾動(dòng)處理函數(shù)
        el.addEventListener("scroll", context.handleScroll);
      },
      //   組件更新的時(shí)候,會(huì)不斷觸發(fā)(最明顯就是data中的響應(yīng)式數(shù)據(jù)變化,會(huì)繼續(xù)執(zhí)行update方法)
      update(el, binding, vnode) {
        const context = vnode.context;
        // 如果加載中或者已經(jīng)加載完了,就移除滾動(dòng)事件
        if (
          (binding?.modifiers?.complated && context.complated) ||
          (binding?.modifiers?.loading && context.loading)
        ) {
          el.removeEventListener("scroll", context.handleScroll);
        } else {
          // 當(dāng)loading和complate都是false的時(shí)候,表示可以繼續(xù)加載
          el.addEventListener("scroll", context.handleScroll);
        }
      },
    });
  },
};

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

/**
 * @Description 用于判斷滾動(dòng)條是否到達(dá)底部
 * @param { Element }
 * @return { Boolean }
 **/
export function checkArriveBottom(el) {
  const clientHeight = el.clientHeight;
  const scrollTop = el.scrollTop;
  const scrollHeight = el.scrollHeight;
  //可以設(shè)置>=就行,這里也可以設(shè)置距離底部一定距離,自定義,不一定非要到達(dá)底部
  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");

總結(jié)

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

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

相關(guān)文章

  • vue3集成electron的過(guò)程

    vue3集成electron的過(guò)程

    本文詳細(xì)介紹了如何在Vue3項(xiàng)目中集成Electron,包括安裝electron和electron-builder兩個(gè)依賴,以及配置.npmrc文件和手動(dòng)修改鏡像源的方法,整個(gè)過(guò)程詳細(xì)記錄了從創(chuàng)建項(xiàng)目、安裝依賴、修改配置、到最終打包部署的每一步
    2024-10-10
  • vue3.0中sass全局的使用過(guò)程

    vue3.0中sass全局的使用過(guò)程

    這篇文章主要介紹了vue3.0中sass全局的使用過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue將毫秒數(shù)轉(zhuǎn)化為正常日期格式的實(shí)例

    vue將毫秒數(shù)轉(zhuǎn)化為正常日期格式的實(shí)例

    今天小編就為大家分享一篇vue將毫秒數(shù)轉(zhuǎn)化為正常日期格式的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • Vue項(xiàng)目中env文件的作用和配置詳解

    Vue項(xiàng)目中env文件的作用和配置詳解

    Vue項(xiàng)目中,.env文件是運(yùn)行項(xiàng)目時(shí)的環(huán)境配置文件,但是在實(shí)際開發(fā)過(guò)程中,有本地開發(fā)環(huán)境、測(cè)試環(huán)境、生產(chǎn)環(huán)境等,不同環(huán)境對(duì)應(yīng)的配置會(huì)不一樣,本文給大家介紹了Vue項(xiàng)目中env文件的作用和配置,需要的朋友可以參考下
    2024-12-12
  • Vue.js+HighCharts實(shí)現(xiàn)動(dòng)態(tài)請(qǐng)求展示時(shí)序數(shù)據(jù)

    Vue.js+HighCharts實(shí)現(xiàn)動(dòng)態(tài)請(qǐng)求展示時(shí)序數(shù)據(jù)

    這篇文章主要為大家詳細(xì)介紹了Vue.js+HighCharts實(shí)現(xiàn)動(dòng)態(tài)請(qǐng)求展示時(shí)序數(shù)據(jù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • vue項(xiàng)目引入遠(yuǎn)程jweixin-1.2.0.js文件并使用詳解

    vue項(xiàng)目引入遠(yuǎn)程jweixin-1.2.0.js文件并使用詳解

    這篇文章主要介紹了vue項(xiàng)目引入遠(yuǎn)程jweixin-1.2.0.js文件并使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • vue+springboot實(shí)現(xiàn)登錄功能

    vue+springboot實(shí)現(xiàn)登錄功能

    這篇文章主要為大家詳細(xì)介紹了vue+springboot實(shí)現(xiàn)登錄功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • vue中各種deep的區(qū)別解析

    vue中各種deep的區(qū)別解析

    在Vue3中,推薦使用::deep作為深度選擇器,它比Vue2中的::v-deep語(yǔ)法更簡(jiǎn)潔,::v-deep、::deep、:deep()、&gt;&gt;&gt;和/deep/都是用于穿透組件作用域的選擇器,但Vue3更傾向于使用::deep或:deep(),感興趣的朋友跟隨小編一起看看吧
    2024-10-10
  • vue.js基于ElementUI封裝了CRUD的彈框組件

    vue.js基于ElementUI封裝了CRUD的彈框組件

    這篇文章主要介紹了vue.js基于ElementUI封裝了CRUD的彈框組件,問(wèn)咋會(huì)給你圍繞主題展開詳細(xì)的內(nèi)容介紹,感興趣的小伙伴可以參考一下
    2022-07-07
  • Vue模板內(nèi)引入的組件樣式覆蓋失效原因及解決

    Vue模板內(nèi)引入的組件樣式覆蓋失效原因及解決

    這篇文章主要介紹了Vue模板內(nèi)引入的組件樣式覆蓋失效原因及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04

最新評(píng)論

伊川县| 和林格尔县| 余庆县| 山阳县| 尚志市| 三河市| 慈利县| 保亭| 清水县| 崇仁县| 元江| 察雅县| 嵊州市| 读书| 天峻县| 天台县| 正镶白旗| 和林格尔县| 阜新市| 漾濞| 东乡族自治县| 仁化县| 青冈县| 定陶县| 江孜县| 繁峙县| 丰县| 南岸区| 兰西县| 通许县| 湖州市| 锦屏县| 临城县| 襄垣县| 富源县| 噶尔县| 当涂县| 固镇县| 天全县| 乌兰县| 博罗县|