vue3如何利用自定義指令實現(xiàn)下拉框分頁懶加載
需求:下拉框一開始請求第一頁的內(nèi)容,滾動到最后的時候,請求第二頁的內(nèi)容,如此反復,直到所有數(shù)據(jù)加載完成。
selectLoadMore.ts
//自定義指令:實現(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ù)單獨寫出來,方便銷毀
const scrollHandler = () => {
const condition = SELECTWRAP_DOM.scrollTop + SELECTWRAP_DOM.clientHeight >= SELECTWRAP_DOM.scrollHeight - 1
if (condition) {
loadFunction()
}
}
//賦值,為了方便銷毀,這里很重要,不然銷毀的時候找不到dom和對應的回調(diào)函數(shù)?。?!
el.dom = SELECTWRAP_DOM
el.event = scrollHandler
//監(jiān)聽滾動事件
SELECTWRAP_DOM.addEventListener('scroll', scrollHandler)
}
},
//銷毀,會在關閉彈窗時觸發(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",因為element-plus中ei-select的選項是使用的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
//當前滾動頁
let page: number
/**
* 自定義指令觸發(fā)的回調(diào)
*/
function loadMore() {
//計算總頁數(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",因為element-plus中el-select的選項是使用的popper.js生成的,無法直接獲取,直接獲取下拉框的dom獲取不到
2、在自定義指令里面銷毀事件的時候,在mounted必須把事件存在el上,不然不好銷毀,一開始是以下這么寫的:發(fā)現(xiàn)這樣不好銷毀,因為在 beforeUnmount拿不到function,this只能按以下這么寫才行,如果單獨把funtion拎出來,this就報錯找不到
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ù)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;
// 當滾動條滾動到最底下的時候執(zhí)行接口加載下一頁
if (condition) {
binding.value && binding.value()
}
});
}
},
}
</script>到此這篇關于vue3如何利用自定義指令實現(xiàn)下拉框分頁懶加載的文章就介紹到這了,更多相關vue3自定義指令分頁懶加載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue組件vue-treeselect箭頭和叉圖標變大問題及解決
這篇文章主要介紹了vue組件vue-treeselect箭頭和叉圖標變大問題及解決方案,具有很好的參考價值,希望對大家有所幫助。2022-07-07
使用Vue3封裝實現(xiàn)支持Base64導出的電子簽名組件
這篇文章主要為大家詳細介紹了使用Vue3封裝實現(xiàn)支持Base64導出的電子簽名組件的相關知識,文中的示例代碼講解詳細,有需要的小伙伴可以了解下2025-03-03
vue項目環(huán)境搭建?啟動?移植操作示例及目錄結(jié)構(gòu)分析
這篇文章主要介紹了vue項目環(huán)境搭建、啟動、項目移植、項目目錄結(jié)構(gòu)分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪2022-04-04

