ElementPlus 中el-select自定義指令實(shí)現(xiàn)觸底加載請(qǐng)求options數(shù)據(jù)的方法
1) 背景:
老項(xiàng)目翻新時(shí),發(fā)現(xiàn)一個(gè)下拉框數(shù)據(jù)非常多,客戶(hù)呢,希望全部數(shù)據(jù)一起展示,意思就是全部數(shù)據(jù)一起返回給前端用于展示。但這會(huì)造成明顯的卡頓。~~明顯的不合理! QAQ!~~
于是壓力給到前端,查詢(xún)資料,各種搜索,最終找到2個(gè)解決方案。
1、在el-select下拉框中添加分頁(yè)組件,讓用戶(hù)點(diǎn)擊下一頁(yè)下一頁(yè)
2、在el-select下拉框中數(shù)據(jù),觸底加載當(dāng)然最終選擇了第二個(gè)方案,用戶(hù)體驗(yàn)會(huì)更好。
由于項(xiàng)目中有多個(gè)地方使用到 且 可能單個(gè)頁(yè)面中會(huì)用到多次,為了復(fù)用選擇了自定義指令的方式去實(shí)現(xiàn)。
2) 先來(lái)看看實(shí)現(xiàn)的效果

3) 思路
- 觸底加載,哪個(gè)元素滾動(dòng)觸底時(shí)加載?
- 承裝下拉框中所有元素的容器(.el-scrollbar__wrap)
- 觸底時(shí),觸發(fā)方法做什么?
- 觸底時(shí),繼續(xù)向后端發(fā)請(qǐng)求獲取下一頁(yè)的數(shù)據(jù),請(qǐng)求回來(lái)的數(shù)據(jù)合并給options
4) 簡(jiǎn)單的寫(xiě)一下.vue文件代碼
接口數(shù)據(jù)是自己用node寫(xiě)的
后端代碼在這里:GitHub - stella99888/tao-express: Vue2+Express
```javascript
<!-- 下拉框觸底加載頁(yè)面 -->
<template>
<div class="m-4">
<p>第一個(gè)select</p>
<el-select v-model="value" v-loadmore="loadmore" :teleported="false" style="width:240px">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<p>第二個(gè)select</p>
<el-select v-model="value" v-loadmore="loadmore" :teleported="false" style="width:240px">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
</template>
<script setup>
import axios from 'axios';
import { onMounted, reactive, ref } from 'vue'
const list = ref([])
const options = ref([])
const option = ref([])
const value = ref([])
const loading = ref(false)
let pageData = reactive({
pageIndex: 1,
pageSize: 10
})
onMounted(() => {
getOptions()
})
const getOptions = () => {
axios.get(`http://localhost:9999/getSelectOptions?pageIndex=${pageData.pageIndex}&pageSize=${pageData.pageSize}`)
.then(res => {
console.log(res.data);
if (res.data.length < 1) {
ElMessage({
message: '沒(méi)有更多數(shù)據(jù)了...',
type: "warning",
});
}
const newOptions = res.data.map((item) => {
return { value: item.name, label: item.index }
})
options.value.push(...newOptions)
})
}
// 觸底了,繼續(xù)發(fā)請(qǐng)求
const loadmore = () => {
pageData.pageIndex = pageData.pageIndex + 1
getOptions()
}
</script>* 注意一下:
1. teleported屬性為官網(wǎng)提供,是否將下拉列表插入至 body 元素,默認(rèn)值為true,插入到body元素中。
> 這是插入body中的

> 這是不插入body中的(可以對(duì)比下)

2. 我們需要將其插入body元素中嗎?如果是單個(gè)頁(yè)面中只出現(xiàn)一個(gè),那影響不大;如果是多個(gè),我們要選中該元素時(shí)就很不方便了。
3. 且,我們這邊使用的是自定義指令的方式,指令在el-select元素上,teleported為false,不插入body時(shí),正好可以在自定義指令中使用el.querySelector('.el-scrollbar__wrap')獲取滾動(dòng)的元素。
5) 自定義指令
前端代碼在這里:GitHub - wwaini/tao-vue3 at release240625
// src/directives/loadmore/index.js
import { debounce } from "lodash";
export default {
mounted(el, binding) {
// 不插入body時(shí),以下方式可獲取元素
// 插入body時(shí),需要以document.querySelector('.el-scrollbar__wrap')獲取
let scrollWrap = el.querySelector('.el-scrollbar__wrap')
// 把監(jiān)聽(tīng)的方法防抖一下
const handle = debounce((e) => {
let scrollDistance = scrollWrap.scrollHeight - scrollWrap.scrollTop
// 比如此處預(yù)留10個(gè)像素的位置用于觸底
if (scrollWrap.clientHeight + 10 > scrollDistance) {
binding.value() // 觸底通知一下,外界
}
}, 170)
// 綁定監(jiān)聽(tīng)滾動(dòng)事件
scrollWrap?.addEventListener('scroll', handle)
// 方法掛載到元素身上便于解綁時(shí)使用
el._hanlde = handle
},
unmounted(el, binding) {
let scrollWrap = document.querySelector('.el-scrollbar__wrap')
scrollWrap?.removeEventListener('scroll', el._hanlde)
el._hanlde = null
}
}// directives/index.js
import loadmore from "./loadmore"
// 自定義指令對(duì)象,用于遍歷注冊(cè)
const directives = {
loadmore
}
// 批量注冊(cè)指令并暴露到main.js中去便于注冊(cè)
export default {
install(app) {
Object.keys(directives).forEach((key) => {
app.directive(key, directives[key])
})
}
}// main.js
import { createApp } from 'vue';
import App from './App.vue';
const app = createApp(App);
// 引入并使用自定義指令
import directive from './directives'
app.use(directive);
app.mount('#app');// src/views/num/six.vue
<!-- 下拉框觸底加載自定義指令 -->
<template>
<div class="m-4">
<p>第一個(gè)select</p>
<el-select v-model="value" v-loadmore="loadmore" :teleported="false" style="width:240px">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<p>第二個(gè)select</p>
<el-select v-model="value" v-loadmore="loadmore" :teleported="false" style="width:240px">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
</template>
<script setup>
import axios from 'axios';
import { onMounted, reactive, ref } from 'vue'
const list = ref([])
const options = ref([])
const option = ref([])
const value = ref([])
const loading = ref(false)
let pageData = reactive({
pageIndex: 1,
pageSize: 10
})
onMounted(() => {
getOptions()
})
const getOptions = () => {
axios.get(`http://localhost:9999/getSelectOptions?pageIndex=${pageData.pageIndex}&pageSize=${pageData.pageSize}`)
.then(res => {
console.log(res.data);
if (res.data.length < 1) {
ElMessage({
message: '沒(méi)有更多數(shù)據(jù)了...',
type: "warning",
});
}
const newOptions = res.data.map((item) => {
return { value: item.name, label: item.index }
})
options.value.push(...newOptions)
})
}
// 觸底了,繼續(xù)發(fā)請(qǐng)求
const loadmore = () => {
pageData.pageIndex = pageData.pageIndex + 1
getOptions()
}
</script>到此這篇關(guān)于ElementPlus 中el-select自定義指令實(shí)現(xiàn)觸底加載請(qǐng)求options數(shù)據(jù)的文章就介紹到這了,更多相關(guān)el-select觸底加載請(qǐng)求options數(shù)據(jù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
element中TimePicker時(shí)間選擇器禁用部分時(shí)間(顯示禁用到分鐘)
這篇文章主要介紹了element中TimePicker時(shí)間選擇器禁用部分時(shí)間(顯示禁用到分鐘),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
前端vue滾動(dòng)條滾動(dòng)監(jiān)聽(tīng)問(wèn)題成功解決辦法
在Vue中監(jiān)聽(tīng)滾動(dòng)事件可以通過(guò)使用指令或者自定義事件來(lái)實(shí)現(xiàn),這篇文章主要給大家介紹了關(guān)于前端vue滾動(dòng)條滾動(dòng)監(jiān)聽(tīng)問(wèn)題成功解決的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-09-09
Vue過(guò)濾器,生命周期函數(shù)和vue-resource簡(jiǎn)單介紹
這篇文章主要介紹了Vue過(guò)濾器,生命周期函數(shù)和vue-resource簡(jiǎn)單介紹,幫助大家更好的理解和使用vue,感興趣的朋友可以了解下2021-01-01
解決vue的router組件component在import時(shí)不能使用變量問(wèn)題
這篇文章主要介紹了解決vue的router組件component在import時(shí)不能使用變量問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07
vue3.0 搭建項(xiàng)目總結(jié)(詳細(xì)步驟)
這篇文章主要介紹了vue3.0 搭建項(xiàng)目總結(jié)(詳細(xì)步驟),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05
VUE遞歸樹(shù)形實(shí)現(xiàn)多級(jí)列表
這篇文章主要為大家詳細(xì)介紹了VUE遞歸樹(shù)形實(shí)現(xiàn)多級(jí)列表,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07
使用vite創(chuàng)建vue3項(xiàng)目的詳細(xì)圖文教程
創(chuàng)建Vue3項(xiàng)目有兩種常見(jiàn)的方式,一種是想vue2版本一樣使用腳手架工具創(chuàng)建,創(chuàng)建vue3項(xiàng)目的腳手架必須是4版本以上的,另一種方法就是使用vite創(chuàng)建,這篇文章主要給大家介紹了關(guān)于如何使用vite創(chuàng)建vue3項(xiàng)目的相關(guān)資料,需要的朋友可以參考下2022-11-11
vue3使用el-radio-group獲取表格數(shù)據(jù)無(wú)法選中問(wèn)題及解決方法
這篇文章主要介紹了vue3使用el-radio-group獲取表格數(shù)據(jù)無(wú)法選中問(wèn)題及解決方法,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-05-05

