由于用 input 实现下拉分页不太理想,转换了一个角度,用 select 实现,以下是具体实现(script-setup TS)

script-setup

<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({ name: 'LabelSelectCpm' })
</script> <script setup lang="ts">
import { ref, reactive } from 'vue'
// const emit = defineEmits([]) // select 绑定的 v-model
const value = ref()
const searchKeyword = ref()
//dom 事件节点
const dom = ref()
const loading = ref(false)
// select-options 数据源
const options = ref([])
// 分页控制
const requsetObj = reactive({
page: 1,
size: 50,
}) /**
* 加载接口数据
* @return Promise
*/
const loadData = async () => {
return new Promise((res, rej) => {
setTimeout(() => {
res(
Array.from(
{ length: requsetObj.size * requsetObj.page },
(v, i) => ({ label: `label${i}`, value: `value${i}` })
)
)
}, 300)
})
} /**
* @param {string} query 输入的搜索关键词
* @param {function} fn 需要在接口数据返回后执行的回调
*/
const remoteMethod = (query: string, fn?: Function) => {
loading.value = true
if (query) {
/* 记录输入的关键词 */
searchKeyword.value = query
loadData().then((res: any) => {
console.log(res)
options.value = res
loading.value = false
fn && fn()
})
} else {
/* 初始化数据逻辑 */
loadData().then((res: any) => {
console.log(res)
options.value = res
loading.value = false
fn && fn()
})
}
} const selectChange = (val: any) => {
const selectVal = options.value.filter((e: any) => e.value == val)
console.log('当前选中', selectVal)
} /* 滚动监听函数 */
const scrollAddEventFn = (e) => {
const self = e.target as any
if (self.scrollHeight - self.scrollTop <= self.clientHeight) {
console.log('分页查询')
requsetObj.page++
remoteMethod(searchKeyword.value)
}
}
const visibleChange = (isShow: any) => {
if (isShow) {
// 下拉框显示时,渲染数据,初始化滚动监听
remoteMethod(searchKeyword.value, () => {
/* 在数据渲染完之后的回调 */
/* 初始化滚动监听 (由于 dom 渲染未完成,所以需要开启一个 timeout 在 1s 后实现监听) */
const parentDom = document.querySelectorAll(
'.el-select-dropdown__wrap.el-scrollbar__wrap.el-scrollbar__wrap--hidden-default'
) as any
setTimeout(() => {
parentDom.forEach((e: any, idx: number) => {
if (
e.querySelector('.LabelSelectCpmBox') &&
e.querySelector('.LabelSelectCpmBox').children &&
e.querySelector('.LabelSelectCpmBox').children.length >
0
) {
dom.value = parentDom[idx]
dom.value.addEventListener(
'scroll',
scrollAddEventFn,
false
)
}
})
}, 1000)
})
} else {
// 移除滚动监听
dom.value?.removeEventListener('scroll', scrollAddEventFn, false)
options.value = []
}
}
</script>

template

<template>
<div class="LabelSelectCpm">
<el-select
v-model="value"
:multiple="false"
filterable
remote
reserve-keyword
placeholder="输入关键词搜索"
:remote-method="remoteMethod"
@change="selectChange"
@visible-change="visibleChange"
:loading="loading"
>
<div class="LabelSelectCpmBox">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</div>
</el-select>
</div>
</template>

css 没有额外的代码,所以就不贴了

最新文章

  1. ASP.NET MVC WEB API必知必会知识点总结
  2. iOS 图片加载导致内存警告
  3. [原创] WINDOWS 7 精简教程之驱动精简 可用于64和32
  4. 性能测试工具Gatling - 设置Recorder
  5. HD1085 Holding Bin-Laden Captive!
  6. 保存网页MHT
  7. Windows7 搜索功能关闭了,怎么重新打开
  8. Set Windows IP by Batch
  9. 完美去除WPF按钮的边框
  10. Maven-项目构建技术(工具)
  11. hdu_2147_kiki&#39;s game(博弈)
  12. DOM4j 操作XML
  13. GitHub上整理的一些资料
  14. C++结束进程 并能显示其父进程
  15. 函数putText()在图片上写文字
  16. 网络通信协议简介(TCP与UDP)
  17. Node.js实战(七)之交互式解释器
  18. CXF创建webservice客户端和服务端
  19. PHP中exit()与die()的区别
  20. JavaEE学习记录(一)--软件系统体系结构

热门文章

  1. Crypto入门 (三)Morse
  2. 【随便翻翻】Steam Deck现在(基本上)不通过预订就能购买到
  3. MySQL代替in之临时表
  4. 在VS中使用Wind数据终端API的经验(一)
  5. c# Visual Studio|There is no editor available for ***,make sure the application for the file type(.vb) is installed问题解决方法
  6. (转)codeblocks 使用研究
  7. python字符操作超全总结
  8. DVWA-XSS (Stored) 存储型XSS
  9. java生态下的后端开发都有哪些技术栈?
  10. #HDU2255#奔小康赚大钱(KM模板题)