el-select自定義指令實(shí)現(xiàn)觸底加載分頁(yè)請(qǐng)求options數(shù)據(jù)(完整代碼和接口可直接用)
問(wèn)題描述
- 某些情況下,下拉框需要做觸底加載,發(fā)請(qǐng)求,獲取option的數(shù)據(jù)
- 為了方便復(fù)用,筆者封裝了一個(gè)自定義指令
- 另外也提供了一個(gè)簡(jiǎn)單的接口,用于演示
- 我們先看看效果圖
效果圖
思路分析
- 為何,不嵌入到
body標(biāo)簽
中呢? - 答曰,更加方便自定義指令管理,如下屬性:
<el-select :popper-append-to-body="false" ...
- 這樣的話,我們可以在自定義指令的鉤子中,可以直接使用
el.querySelector(xxx)
去選中下拉框的選項(xiàng)彈出層了。就不用使用document.querySelector(xxx)
- 因?yàn)椋羰乔度氲?code>body層,若是同一個(gè)頁(yè)面,有多個(gè)
el-select
就不太好控制管理了 - 注意下方的兩張圖,
option
選項(xiàng)彈出層
不嵌入到body層
嵌入到body層
注意事項(xiàng)二
寫(xiě)一個(gè)模擬分頁(yè)函數(shù)用在express接口中
如下代碼+注釋?zhuān)?/p>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>分頁(yè)請(qǐng)求</title> </head> <body> <script> function query(pageIndex, pageSize) { // 定義一個(gè)數(shù)組用于存放所有的模擬數(shù)據(jù) let arr = [] // 循環(huán)追加 for (let i = 1; i < 100; i++) { arr.push({ name: '孫悟空' + i, age: 500 + i, id: i }) } // 根據(jù)第幾頁(yè),一頁(yè)多少條來(lái)取到對(duì)應(yīng)項(xiàng) let res = arr.slice( (pageIndex - 1) * pageSize, pageIndex * pageSize, ) // 操作完畢,返回吐出來(lái),供外界使用 return res } console.log('第一頁(yè),要10條數(shù)據(jù):', query(1, 10)); console.log('第二頁(yè),要10條數(shù)據(jù):', query(2, 10)); </script> </body> </html>
如下打印結(jié)果圖:
用在express接口中:
// 模擬分頁(yè)查詢 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)) // 返回請(qǐng)求結(jié)果 })
注意事項(xiàng)三
- 注意,要按下以下的方式,進(jìn)行語(yǔ)法書(shū)寫(xiě)
- 這是一種寫(xiě)法規(guī)范,因?yàn)?,事件監(jiān)聽(tīng)和解綁的句柄是一個(gè)整體
// 綁定事件,句柄handle函數(shù),要是一個(gè)整體 dom.addEventListener('scroll', handle) // 移除事件,句柄handle函數(shù),也要對(duì)應(yīng)是一個(gè)整體 dom.removeEventListener('scroll', handle) // 定義一個(gè)句柄函數(shù),為debounce套殼子的方式 import { debounce } from "lodash"; const handle = debounce((e) => { // xxxxxxxx }, 170)
實(shí)現(xiàn)思路
首先給el-select添加:popper-append-to-body="false"
屬性,使其在內(nèi)部管理,這樣的話,在自定義指令中的鉤子函數(shù)中,可以直接選中操作,獲取到el-option滾動(dòng)的容器
inserted(el, binding, vnode) { let scrollWrap = el.querySelector('.el-select-dropdown .el-scrollbar .el-select-dropdown__wrap') }
- 然后,給滾動(dòng)容器綁定監(jiān)聽(tīng)事件,根據(jù)幾個(gè)高度,判斷是否觸底(最好預(yù)留幾個(gè)像素)
- 若是觸底了,就觸發(fā)外界傳遞的觸底函數(shù)執(zhí)行,這樣的話,就是通知外界繼續(xù)發(fā)請(qǐng)求,繼續(xù)獲取el-option數(shù)據(jù)
- 當(dāng)然,這里的自定義指令,要傳遞一個(gè)函數(shù)(把函數(shù)當(dāng)做參數(shù)傳遞進(jìn)來(lái),就是高階函數(shù)的思想)
- 最后,別忘了,解綁事件即可
完整代碼-自定義指令
import { debounce } from "lodash"; export default { inserted(el, binding, vnode) { // 獲取滾動(dòng)容器dom let scrollWrap = el.querySelector('.el-select-dropdown .el-scrollbar .el-select-dropdown__wrap') // 把監(jiān)聽(tīng)的句柄防抖一下 const handle = debounce((e) => { let scrollDistance = scrollWrap.scrollHeight - scrollWrap.scrollTop // 比如此處預(yù)留6個(gè)像素的位置用于觸底 if (scrollWrap.clientHeight + 6 > scrollDistance) { binding.value() // 觸底通知一下,外界 } }, 170) // 綁定監(jiān)聽(tīng)滾動(dòng)事件 scrollWrap?.addEventListener('scroll', handle) // 把監(jiān)聽(tīng)的句柄掛載到元素身上便于解綁時(shí)使用 el._hanlde = handle }, unbind() { // 獲取滾動(dòng)容器dom let scrollWrap = el.querySelector('.el-select-dropdown .el-scrollbar .el-select-dropdown__wrap') // 解綁 scrollWrap?.removeEventListener('scroll', el._hanlde) // 清空 delete el._hanlde; } }
完整代碼-給el-select使用這個(gè)自定義指令
<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() { // 筆者自己的服務(wù)器,給大家提供了一個(gè)分頁(yè)接口 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('沒(méi)數(shù)據(jù)了') // 合并一下下拉框數(shù)據(jù) this.options = [ ...this.options, ...data ] }, // 觸底了,繼續(xù)發(fā)請(qǐng)求 loadmore() { this.pageIndex = this.pageIndex + 1 this.getOptions() }, }, }; </script>
項(xiàng)目演示和github倉(cāng)庫(kù)
- 為了便于大家更直觀的看效果
- 筆者把代碼推到自己的github上去了
- 并且部署到自己的服務(wù)器上了,點(diǎn)擊即看
項(xiàng)目演示網(wǎng)站:http://ashuai.work:8888/#/selectDown
項(xiàng)目github地址:https://github.com/shuirongshuifu/elementSrcCodeStudy
若是道友的項(xiàng)目中,還需要做el-select遠(yuǎn)程搜索,可以參見(jiàn)作者的這篇文章:https://segmentfault.com/a/1190000039097410
到此這篇關(guān)于el-select自定義指令實(shí)現(xiàn)觸底加載分頁(yè)請(qǐng)求options數(shù)據(jù)(附上完整代碼和接口可直接用)的文章就介紹到這了,更多相關(guān)el-select觸底分頁(yè)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue動(dòng)態(tài)添加路由后刷新頁(yè)面白屏問(wèn)題及解決
這篇文章主要介紹了vue動(dòng)態(tài)添加路由后刷新頁(yè)面白屏問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04Vue+Element一步步實(shí)現(xiàn)動(dòng)態(tài)添加Input_輸入框案例
這篇文章主要介紹了Vue+Element一步步實(shí)現(xiàn)動(dòng)態(tài)添加Input_輸入框案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09vue使用動(dòng)態(tài)添加路由(router.addRoutes)加載權(quán)限側(cè)邊欄的方式
這篇文章主要介紹了vue使用動(dòng)態(tài)添加路由(router.addRoutes)加載權(quán)限側(cè)邊欄的方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06Vue3處理錯(cuò)誤邊界(error boundaries)的示例代碼
在開(kāi)發(fā) Vue 3 應(yīng)用時(shí),處理錯(cuò)誤邊界(Error Boundaries)是一個(gè)重要的考量,在 Vue 3 中實(shí)現(xiàn)錯(cuò)誤邊界的方式與 React 等其他框架有所不同,下面,我們將深入探討 Vue 3 中如何實(shí)現(xiàn)錯(cuò)誤邊界,并提供一些示例代碼幫助理解什么是錯(cuò)誤邊界,需要的朋友可以參考下2024-10-10vue實(shí)現(xiàn)form表單與table表格的數(shù)據(jù)關(guān)聯(lián)功能示例
這篇文章主要介紹了vue實(shí)現(xiàn)form表單與table表格的數(shù)據(jù)關(guān)聯(lián)功能,涉及vue.js表單事件響應(yīng)及頁(yè)面元素屬性動(dòng)態(tài)操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-01-01淺談vue?腳手架文件結(jié)構(gòu)及加載過(guò)程
這篇文章主要介紹了vue腳手架文件結(jié)構(gòu)及加載過(guò)程淺談,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08