vue對(duì)el-autocomplete二次封裝增加下拉分頁(yè)
項(xiàng)目中的聯(lián)想輸入框現(xiàn)在都是采用的el-autocomplete實(shí)現(xiàn)的,但是隨著數(shù)據(jù)量越來(lái)越多,產(chǎn)品要求一次不要返回所有的聯(lián)想數(shù)據(jù),要做分頁(yè)處理,所以需要添加一個(gè)分頁(yè)的功能。
注:看懂下面的代碼需要先對(duì)vue和element有一定的學(xué)習(xí)。
廢話不多數(shù),先上完整代碼
<template> <el-autocomplete ref="autocomplete" value-key="value" v-scrollLoad="selectLoadMore" v-loading="loading" v-model="state" :fetch-suggestions="querySearch" :placeholder="placeholder" :trigger-on-focus="false" @select="handleSelect" ></el-autocomplete> </template> <script> export default { name: 'InputLoadMore', props: { // 封裝的查數(shù)據(jù)方法 getOptionFn: { require: true }, // 后端定義的聯(lián)想的key searchKey: { type: String, require: true }, // v-model的綁定值 value: { type: String, require: true }, // placehoder placeholder: { type: String, default: '請(qǐng)輸入' } }, data() { return { state: '', loading: false, page: 1, pageTotal: 0 } }, watch: { state(val) { this.$emit('input', val) }, value(val) { this.state = val } }, directives: { // 自定義指令,監(jiān)聽(tīng)下拉框的滾動(dòng),滾動(dòng)到底部就加載下一頁(yè) scrollLoad: { bind(el, binding, vnode) { let wrapDom = el.querySelector('.el-autocomplete-suggestion__wrap') let listDom = el.querySelector('.el-autocomplete-suggestion__wrap .el-autocomplete-suggestion__list') wrapDom.addEventListener( 'scroll', e => { // 注意load的使用,節(jié)流 let condition = wrapDom.offsetHeight + wrapDom.scrollTop + 10 - listDom.offsetHeight if (condition > 0 && !vnode.context.loading) { //滾動(dòng)到底部則執(zhí)行滾動(dòng)方法load,binding.value就是v-scrollLoad綁定的值,加()表示執(zhí)行綁定的方法 binding.value() } }, false ) } } }, methods: { async querySearch(queryString, cb) { this.page = 1 this.loading = true try { let { result } = await this.getOptionFn({ page: 1, pageSize: 50, [this.searchKey]: queryString }) // 根據(jù)實(shí)際情況修改下面的代碼,展示數(shù)據(jù) if (result.rows) { let arr = [] result.rows.forEach(item => { arr.push({ value: item }) }) cb(arr) } else { cb([]) } this.pageTotal = result.total || 0 } catch(e) { // console.log(e) } finally { this.loading = false } }, handleSelect(item) {}, // 加載更多 async selectLoadMore() { if(Number(this.pageTotal) <= this.$refs['autocomplete'].$data.suggestions.length) { return } this.page = this.page + 1 this.loading = true try { let { result } = await this.getOptionFn({ page: this.page, pageSize: 50, [this.searchKey]: this.state }) // 根據(jù)實(shí)際情況修改下面的代碼,展示數(shù)據(jù) if (result.rows) { const arr = result.rows.map(item => { return { value: item } }) // 將數(shù)據(jù)添加到下拉列表 this.$refs['autocomplete'].$data.suggestions = this.$refs['autocomplete'].$data.suggestions.concat(arr) } this.pageTotal = result.total || 0 } catch(e) { // console.log(e) } finally { this.loading = false } } } } </script> </script>
下面對(duì)主要的地方進(jìn)行講解。
1.自定義指令實(shí)現(xiàn)下拉加載更多。
主要代碼
// 自定義指令,監(jiān)聽(tīng)下拉框的滾動(dòng),滾動(dòng)到底部就加載下一頁(yè) scrollLoad: { bind(el, binding, vnode) { let wrapDom = el.querySelector('.el-autocomplete-suggestion__wrap') let listDom = el.querySelector('.el-autocomplete-suggestion__wrap .el-autocomplete-suggestion__list') wrapDom.addEventListener( 'scroll', e => { // 注意load的使用,節(jié)流 let condition = wrapDom.offsetHeight + wrapDom.scrollTop + 10 - listDom.offsetHeight if (condition > 0 && !vnode.context.loading) { //滾動(dòng)到底部則執(zhí)行滾動(dòng)方法load,binding.value就是v-scrollLoad綁定的值,加()表示執(zhí)行綁定的方法 binding.value() } }, false ) }
上面主要是運(yùn)用了vue的自定義指令的bind鉤子。不太了解的可以先看這個(gè)https://cn.vuejs.org/v2/guide/custom-directive.html 。bind有四個(gè)參數(shù)(el、binding、vnode、oldVnode)這里用前三個(gè),el代表綁定的元素,用來(lái)操作dom,這里用來(lái)添加scroll事件,以及計(jì)算下拉框是否滑動(dòng)到底部(注意計(jì)算中的+10高度);binding是一個(gè)對(duì)象,包含舊值、新值、指令名等,這里主要用綁定值value,用來(lái)執(zhí)行加載更多的方法;Vnode指的是虛擬節(jié)點(diǎn),這里取他的context即為this控制loading來(lái)節(jié)流。
2.增加props(getOptionFn、searchKey、value、placeholder)抽離業(yè)務(wù)。成為公共組件
- getOptionFn為接口封裝的方法。fetch-suggestions和加載更多里面都要用到
- searchKey表示接口需要傳的參數(shù)的key,不同的接口的key可能不一致。
- value是外面v-modle的綁定值,注意在watch里面設(shè)置值,不知道的可以看看v-model的實(shí)現(xiàn)原理。
- placeholder不解釋
3.可能需要解釋的
- 在加載到更多數(shù)據(jù)后怎么把輸入加到下拉里面?
this.$refs['autocomplete'].$data.suggestions // 下拉的列表
- 怎么避免加載完了還加載更多。
這里是用的數(shù)量比較,也可以加一個(gè)標(biāo)識(shí)符,加載完了設(shè)置為true,變化條件后設(shè)為false。
if(Number(this.pageTotal) <= this.$refs['autocomplete'].$data.suggestions.length) { return }
到此這篇關(guān)于vue對(duì)el-autocomplete二次封裝增加下拉分頁(yè)的文章就介紹到這了,更多相關(guān)vue el-autocomplete下拉分頁(yè)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Vue中 v-for循環(huán)列表控制按鈕隱藏顯示功能
這篇文章主要介紹了使用Vue中 v-for循環(huán)列表控制按鈕隱藏顯示功能,需要的朋友可以參考下2019-04-04使用vue-cli(vue腳手架)快速搭建項(xiàng)目的方法
本篇文章主要介紹了使用vue-cli(vue腳手架)快速搭建項(xiàng)目的方法,vue-cli 是一個(gè)官方發(fā)布 vue.js 項(xiàng)目腳手架,使用 vue-cli 可以快速創(chuàng)建 vue 項(xiàng)目,感興趣的小伙伴們可以參考一下2018-05-05vue項(xiàng)目中的遇錯(cuò):Invalid?Host?header問(wèn)題
這篇文章主要介紹了vue項(xiàng)目中的遇錯(cuò):Invalid?Host?header問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07用Axios Element實(shí)現(xiàn)全局的請(qǐng)求loading的方法
本篇文章主要介紹了用Axios Element實(shí)現(xiàn)全局的請(qǐng)求loading的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03vue項(xiàng)目如何設(shè)置全局字體樣式font-family
這篇文章主要介紹了vue項(xiàng)目如何設(shè)置全局字體樣式font-family問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11Vue使用v-viewer實(shí)現(xiàn)圖片預(yù)覽
這篇文章主要為大家詳細(xì)介紹了Vue使用v-viewer實(shí)現(xiàn)圖片預(yù)覽,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-10-10vue-admin-template配置快捷導(dǎo)航的代碼(標(biāo)簽導(dǎo)航欄)
這篇文章主要介紹了vue-admin-template配置快捷導(dǎo)航的方法(標(biāo)簽導(dǎo)航欄),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09