el-select自定義指令實現(xiàn)觸底加載分頁請求options數(shù)據(jù)(完整代碼和接口可直接用)
問題描述
- 某些情況下,下拉框需要做觸底加載,發(fā)請求,獲取option的數(shù)據(jù)
- 為了方便復用,筆者封裝了一個自定義指令
- 另外也提供了一個簡單的接口,用于演示
- 我們先看看效果圖
效果圖

思路分析
- 為何,不嵌入到
body標簽中呢? - 答曰,更加方便自定義指令管理,如下屬性:
<el-select :popper-append-to-body="false" ...- 這樣的話,我們可以在自定義指令的鉤子中,可以直接使用
el.querySelector(xxx)去選中下拉框的選項彈出層了。就不用使用document.querySelector(xxx) - 因為,若是嵌入到
body層,若是同一個頁面,有多個el-select就不太好控制管理了 - 注意下方的兩張圖,
option選項彈出層
不嵌入到body層

嵌入到body層

注意事項二
寫一個模擬分頁函數(shù)用在express接口中
如下代碼+注釋:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>分頁請求</title>
</head>
<body>
<script>
function query(pageIndex, pageSize) {
// 定義一個數(shù)組用于存放所有的模擬數(shù)據(jù)
let arr = []
// 循環(huán)追加
for (let i = 1; i < 100; i++) {
arr.push({
name: '孫悟空' + i,
age: 500 + i,
id: i
})
}
// 根據(jù)第幾頁,一頁多少條來取到對應項
let res = arr.slice(
(pageIndex - 1) * pageSize,
pageIndex * pageSize,
)
// 操作完畢,返回吐出來,供外界使用
return res
}
console.log('第一頁,要10條數(shù)據(jù):', query(1, 10));
console.log('第二頁,要10條數(shù)據(jù):', query(2, 10));
</script>
</body>
</html>如下打印結果圖:

用在express接口中:
// 模擬分頁查詢
route.get('/pageData', (req, res) => {
res.header('Access-Control-Allow-Origin', '*'); // 允許跨域
let pageIndex = req.query.pageIndex // 取餐
let pageSize = req.query.pageSize // 取餐
function query(pageIndex, pageSize) {
let arr = []
for (let i = 1; i < 100; i++) {
arr.push({
name: '孫悟空' + i,
age: 500 + i,
id: i
})
}
let res = arr.slice(
(pageIndex - 1) * pageSize,
pageIndex * pageSize,
)
return res
}
res.send(query(pageIndex, pageSize)) // 返回請求結果
})注意事項三
- 注意,要按下以下的方式,進行語法書寫
- 這是一種寫法規(guī)范,因為,事件監(jiān)聽和解綁的句柄是一個整體
// 綁定事件,句柄handle函數(shù),要是一個整體
dom.addEventListener('scroll', handle)
// 移除事件,句柄handle函數(shù),也要對應是一個整體
dom.removeEventListener('scroll', handle)
// 定義一個句柄函數(shù),為debounce套殼子的方式
import { debounce } from "lodash";
const handle = debounce((e) => {
// xxxxxxxx
}, 170)實現(xiàn)思路
首先給el-select添加:popper-append-to-body="false"屬性,使其在內(nèi)部管理,這樣的話,在自定義指令中的鉤子函數(shù)中,可以直接選中操作,獲取到el-option滾動的容器
inserted(el, binding, vnode) {
let scrollWrap = el.querySelector('.el-select-dropdown .el-scrollbar .el-select-dropdown__wrap')
}- 然后,給滾動容器綁定監(jiān)聽事件,根據(jù)幾個高度,判斷是否觸底(最好預留幾個像素)
- 若是觸底了,就觸發(fā)外界傳遞的觸底函數(shù)執(zhí)行,這樣的話,就是通知外界繼續(xù)發(fā)請求,繼續(xù)獲取el-option數(shù)據(jù)
- 當然,這里的自定義指令,要傳遞一個函數(shù)(把函數(shù)當做參數(shù)傳遞進來,就是高階函數(shù)的思想)
- 最后,別忘了,解綁事件即可
完整代碼-自定義指令
import { debounce } from "lodash";
export default {
inserted(el, binding, vnode) {
// 獲取滾動容器dom
let scrollWrap = el.querySelector('.el-select-dropdown .el-scrollbar .el-select-dropdown__wrap')
// 把監(jiān)聽的句柄防抖一下
const handle = debounce((e) => {
let scrollDistance = scrollWrap.scrollHeight - scrollWrap.scrollTop
// 比如此處預留6個像素的位置用于觸底
if (scrollWrap.clientHeight + 6 > scrollDistance) {
binding.value() // 觸底通知一下,外界
}
}, 170)
// 綁定監(jiān)聽滾動事件
scrollWrap?.addEventListener('scroll', handle)
// 把監(jiān)聽的句柄掛載到元素身上便于解綁時使用
el._hanlde = handle
},
unbind() {
// 獲取滾動容器dom
let scrollWrap = el.querySelector('.el-select-dropdown .el-scrollbar .el-select-dropdown__wrap')
// 解綁
scrollWrap?.removeEventListener('scroll', el._hanlde)
// 清空
delete el._hanlde;
}
}完整代碼-給el-select使用這個自定義指令
<template>
<div class="box">
<el-select v-model="value" filterable :popper-append-to-body="false" v-down="loadmore" clearable>
<el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</div>
</template>
<script>
import axios from "axios";
export default {
data() {
return {
options: [],
value: '',
pageIndex: 1,
pageSize: 20
};
},
mounted() {
this.getOptions()
},
methods: {
async getOptions() {
// 筆者自己的服務器,給大家提供了一個分頁接口
let url = `http://ashuai.work/api/pageData?pageIndex=${this.pageIndex}&pageSize=${this.pageSize}`
let { data } = await axios.get(url)
if (data.length == 0) return this.$message('沒數(shù)據(jù)了')
// 合并一下下拉框數(shù)據(jù)
this.options = [
...this.options,
...data
]
},
// 觸底了,繼續(xù)發(fā)請求
loadmore() {
this.pageIndex = this.pageIndex + 1
this.getOptions()
},
},
};
</script>項目演示和github倉庫
- 為了便于大家更直觀的看效果
- 筆者把代碼推到自己的github上去了
- 并且部署到自己的服務器上了,點擊即看
項目演示網(wǎng)站:http://ashuai.work:8888/#/selectDown
項目github地址:https://github.com/shuirongshuifu/elementSrcCodeStudy
若是道友的項目中,還需要做el-select遠程搜索,可以參見作者的這篇文章:https://segmentfault.com/a/1190000039097410
到此這篇關于el-select自定義指令實現(xiàn)觸底加載分頁請求options數(shù)據(jù)(附上完整代碼和接口可直接用)的文章就介紹到這了,更多相關el-select觸底分頁內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Vue+Element一步步實現(xiàn)動態(tài)添加Input_輸入框案例
這篇文章主要介紹了Vue+Element一步步實現(xiàn)動態(tài)添加Input_輸入框案例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09
vue使用動態(tài)添加路由(router.addRoutes)加載權限側(cè)邊欄的方式
這篇文章主要介紹了vue使用動態(tài)添加路由(router.addRoutes)加載權限側(cè)邊欄的方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06
Vue3處理錯誤邊界(error boundaries)的示例代碼
在開發(fā) Vue 3 應用時,處理錯誤邊界(Error Boundaries)是一個重要的考量,在 Vue 3 中實現(xiàn)錯誤邊界的方式與 React 等其他框架有所不同,下面,我們將深入探討 Vue 3 中如何實現(xiàn)錯誤邊界,并提供一些示例代碼幫助理解什么是錯誤邊界,需要的朋友可以參考下2024-10-10
vue實現(xiàn)form表單與table表格的數(shù)據(jù)關聯(lián)功能示例
這篇文章主要介紹了vue實現(xiàn)form表單與table表格的數(shù)據(jù)關聯(lián)功能,涉及vue.js表單事件響應及頁面元素屬性動態(tài)操作相關實現(xiàn)技巧,需要的朋友可以參考下2019-01-01

