vue3如何利用自定義指令實(shí)現(xiàn)下拉框分頁懶加載
需求:下拉框一開始請求第一頁的內(nèi)容,滾動到最后的時候,請求第二頁的內(nèi)容,如此反復(fù),直到所有數(shù)據(jù)加載完成。
selectLoadMore.ts
//自定義指令:實(shí)現(xiàn)下拉框下拉到末尾時,加載下一頁的內(nèi)容
// 使用時傳兩個參數(shù),一個是下拉框的class,一個是下拉框滾動到末尾時觸發(fā)的函數(shù),比如:
// v-el-select-loadmore="{
// selector: '.myOption .el-select-dropdown .el-select-dropdown__wrap',
// loadFunction: loadMore
// }"
export default {
mounted(el, binding) {
//解構(gòu)傳來的值
const {
value: { selector, loadFunction }
} = binding
const SELECTWRAP_DOM = document.querySelector(selector)
if (SELECTWRAP_DOM) {
// 監(jiān)聽事件的處理函數(shù),把函數(shù)單獨(dú)寫出來,方便銷毀
const scrollHandler = () => {
const condition = SELECTWRAP_DOM.scrollTop + SELECTWRAP_DOM.clientHeight >= SELECTWRAP_DOM.scrollHeight - 1
if (condition) {
loadFunction()
}
}
//賦值,為了方便銷毀,這里很重要,不然銷毀的時候找不到dom和對應(yīng)的回調(diào)函數(shù)?。?!
el.dom = SELECTWRAP_DOM
el.event = scrollHandler
//監(jiān)聽滾動事件
SELECTWRAP_DOM.addEventListener('scroll', scrollHandler)
}
},
//銷毀,會在關(guān)閉彈窗時觸發(fā)(這里的el-select寫在彈窗里)
beforeUnmount(el) {
if (el.dom) {
el.dom.removeEventListener('scroll', el.event)
}
}
}記得在main.ts里面注冊成全局組件?。。?!
main.ts
import vElSelectLoadmore from '@/utils/tools/selectLoadMore'
app.directive('el-select-loadmore', vElSelectLoadmore) //全局自定義指令
app.mount('#app')使用的vue文件
//使用時在指令里傳值,這里有個坑!
//在el-select給一個參數(shù)popper-class="myOption",因?yàn)閑lement-plus中ei-select的選項(xiàng)是使用的popper.js生成的,無法直接獲取,直接獲取下拉框的dom獲取不到
<el-select
v-el-select-loadmore="{
selector: '.myOption .el-select-dropdown .el-select-dropdown__wrap',
loadFunction: loadMore
}"
v-model="userForm.accountName"
placeholder="請選擇用戶"
popper-class="myOption"
>
<el-option
v-for="(item, index) in userData"
v-loading="optionLoading(index)"
:key="item.id"
:label="item.username"
:value="item.id"
/>
</el-select>
//總共的數(shù)據(jù)條數(shù)
let totalCount: number = 0
//當(dāng)前滾動頁
let page: number
/**
* 自定義指令觸發(fā)的回調(diào)
*/
function loadMore() {
//計(jì)算總頁數(shù)
let maxPagSize: number = Math.max(Math.ceil(totalCount / 10), 1)
//不超過總頁數(shù)才發(fā)請求
if (page < maxPagSize) {
page += 1
//發(fā)請求,獲得接口數(shù)據(jù)
getUserListWrap(page, 10)
}
}
/**
* 控制下拉框loding是否出現(xiàn),isOptionLoading是在getUserListWrap請求函數(shù)里面的,userData是請求函數(shù)獲得是下拉框數(shù)據(jù),這樣可以使下拉到最后一個option的時候,出現(xiàn)loding效果,更加完善美觀
* @param index 下拉框循環(huán)的index
*/
function optionLoading(index: number): boolean {
if (isOptionLoading.value && index == userData.length - 1) {
return true
} else {
return false
}
}總結(jié):
1、 在el-select給一個參數(shù)popper-class="myOption",因?yàn)閑lement-plus中el-select的選項(xiàng)是使用的popper.js生成的,無法直接獲取,直接獲取下拉框的dom獲取不到
2、在自定義指令里面銷毀事件的時候,在mounted必須把事件存在el上,不然不好銷毀,一開始是以下這么寫的:發(fā)現(xiàn)這樣不好銷毀,因?yàn)樵?nbsp;beforeUnmount拿不到function,this只能按以下這么寫才行,如果單獨(dú)把funtion拎出來,this就報(bào)錯找不到
export default {
mounted(el, binding) {
const {
value: { selector, loadFunction }
} = binding
const SELECTWRAP_DOM = document.querySelector(selector)
if (SELECTWRAP_DOM) {
SELECTWRAP_DOM.addEventListener('scroll', function () {
const condition = this.scrollTop + this.clientHeight >= this.scrollHeight - 1
if (condition) {
loadFunction()
}
})
}
}
}vue3的demo代碼如下:
<template>
<el-form-item label="用戶名稱:">
<el-select
popper-class="myOption"
v-model="accountName"
placeholder="請輸入或選擇用戶"
v-el-select-loadmore="loadMore">
<el-option v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
</template>
<script setup lang="ts">
import {ref,onMounted} from 'vue'
let page = ref(1)
let pageSize = ref(10)
let total = 100
let totalCount=6
let stopLoading = false
let accountName = ref('')
const options = ref([])
onMounted(() => {
options.value.length=0
loadOptions(1)
})
function loadMore() {
//這里設(shè)置接口的最大頁數(shù)totalCount為6,超過6頁就沒數(shù)據(jù)了
if (page.value <= totalCount) {
page.value += 1;
//獲得接口數(shù)據(jù)
loadOptions(page.value);
}
}
function loadOptions(page:number) {
// 模擬接口發(fā)送數(shù)據(jù),異步加載數(shù)據(jù)
setTimeout(() => {
for (let i = (page-1)*10+1; i <= page*10; i++) {
options.value.push({
value: `Option${i}`,
label: `Option${i}`
});
}
}, 500);
}
//在自定義指令
const vElSelectLoadmore = {
mounted(el: any, binding: any) {
// 坑:
const SELECTWRAP_DOM:Element|null = document.querySelector(
'.myOption .el-select-dropdown .el-select-dropdown__wrap'
);
if (SELECTWRAP_DOM) {
SELECTWRAP_DOM.addEventListener('scroll', function () {
const condition = this.scrollTop+this.clientHeight >= this.scrollHeight-1;
// 當(dāng)滾動條滾動到最底下的時候執(zhí)行接口加載下一頁
if (condition) {
binding.value && binding.value()
}
});
}
},
}
</script>到此這篇關(guān)于vue3如何利用自定義指令實(shí)現(xiàn)下拉框分頁懶加載的文章就介紹到這了,更多相關(guān)vue3自定義指令分頁懶加載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue3中實(shí)現(xiàn)組件通信的方法總結(jié)
在Vue3中,有多種方法可以實(shí)現(xiàn)組件之間的通信,本文就通過代碼示例給大家總結(jié)一些vue3實(shí)現(xiàn)組件通信的常用方法,需要的朋友可以參考下2023-06-06
前端實(shí)現(xiàn)不同角色登入展示不同頁面效果實(shí)例
要實(shí)現(xiàn)不同角色登錄跳轉(zhuǎn)不同的前端頁面,可以在登錄成功后,根據(jù)用戶的角色信息,使用路由跳轉(zhuǎn)到不同的頁面,這篇文章主要給大家介紹了關(guān)于前端實(shí)現(xiàn)不同角色登入展示不同頁面效果的相關(guān)資料,需要的朋友可以參考下2024-08-08
vue+iview 兼容IE11瀏覽器的實(shí)現(xiàn)方法
這篇文章主要介紹了vue+iview 兼容IE11瀏覽器的實(shí)現(xiàn)方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-01-01
element el-table表格的二次封裝實(shí)現(xiàn)(附表格高度自適應(yīng))
這篇文章主要介紹了element el-table表格的二次封裝實(shí)現(xiàn)(附表格高度自適應(yīng)),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
vue實(shí)現(xiàn)點(diǎn)擊按鈕倒計(jì)時
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)點(diǎn)擊按鈕倒計(jì)時,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-07-07
VUE?html5-qrcode實(shí)現(xiàn)H5掃一掃功能實(shí)例
這篇文章主要給大家介紹了關(guān)于VUE?html5-qrcode實(shí)現(xiàn)H5掃一掃功能的相關(guān)資料,html5-qrcode是輕量級和跨平臺的QR碼和條形碼掃碼的JS庫,集成二維碼、條形碼和其他一些類型的代碼掃描功能,需要的朋友可以參考下2023-08-08
使用this.$router.go(-1)遇到的一些問題及解決
這篇文章主要介紹了使用this.$router.go(-1)遇到的一些問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12
layui實(shí)際項(xiàng)目使用過程中遇到的兼容性問題及解決
這篇文章主要介紹了layui實(shí)際項(xiàng)目使用過程中遇到的兼容性問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04

