第一步,創(chuàng)建select-load-more.js文件
// 定義全局自定義指令
import Vue from 'vue'
const selectLazyLoad = function(Vue) {
// el-select組件數(shù)據(jù)過多,使用翻頁加載數(shù)據(jù)指令
Vue.directive('selectLazyLoad', {
bind(el, binding) {
const SELECT_WRAP_DOM = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap')
SELECT_WRAP_DOM.addEventListener('scroll', function() {
// toFixed:把this.scrollTop轉(zhuǎn)換為整數(shù),兼容不同版本瀏覽器
const condition = this.scrollHeight - this.scrollTop.toFixed(0) <= this.clientHeight
if (condition) binding.value()
})
}
})
}
if (window.Vue) {
Vue.use(selectLazyLoad)
}
export default selectLazyLoad
第二步, 在main.js中注冊(cè)引入自定義指令
import selectLazyLoad from './directive/select-load-more' //引入
Vue.use(selectLazyLoad) // 使用自定義指令
第三步, 創(chuàng)建公共組件并在組件中使用自定義指令v-selectLazyLoad
<template v-slot>
<el-select
v-model="currentBranchNumber"
v-selectLazyLoad:pageNum="loadMoreData(pageNum)"
class="w-72"
:dropdown-style="{maxHeight: '400px', overflow: 'auto'}"
placeholder="可根據(jù)機(jī)構(gòu)ID或機(jī)構(gòu)名稱篩選"
filterable
clearable
remote
:remote-method="onSearch"
:loading="loading"
@clear="clearSelect"
@focus="focusSelect"
>
<el-option v-for="item in branchTreeData" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</template>
<script>
import axios from 'axios'
export default {
name: 'BranchTreeSelect',
props: {
branchNumber: {
type: String,
default: ''
}
},
data() {
return {
branchTreeData: [],
pageNum: 1,
currentBranchNumber: '',
allowSearchFlag: true, // 是否允許檢索, 防止連續(xù)輸入時(shí)未組裝好數(shù)據(jù)就再次檢索
loading: false,
queryParam: { // 查詢后端所用參數(shù)對(duì)象, 可根據(jù)自己需求變更請(qǐng)求參數(shù)對(duì)象
'xCode': '', // 模糊檢索code
'xName': '', // 模糊檢索name
'xParentCode': 'AYBBRNNO',
'xType': '',
'xFormat': 'Y',
'xPage': 1,
'xPageSize': 50
}
}
},
watch: {
'currentBranchNumber': { // 選中數(shù)據(jù)改變時(shí),調(diào)用父組件的setBranchNumber方法,并傳入選中的值
handler(val) {
if (val) {
this.$emit('setBranchNumber', this.currentBranchNumber.toString().split(':')[0])
} else {
this.$emit('setBranchNumber', '')
}
}
},
'pageNum': { // 當(dāng)前頁數(shù)改變時(shí), 重新觸發(fā)查詢
handler(val) {
if (val) {
this.queryParam.xPage = val
this.queryBranchData('', true)
}
}
}
},
created() { // 組件實(shí)例創(chuàng)建后(data和methods已經(jīng)初始化完畢), 請(qǐng)求后端數(shù)據(jù)
this.queryBranchData()
},
methods: {
loadMoreData() { // 數(shù)據(jù)到底部繼續(xù)滑動(dòng),會(huì)自動(dòng)觸發(fā)頁數(shù)+1
return () => {
this.pageNum += 1
}
},
onSearch(val) { // 檢索功能, 后端可以支持模糊檢索
if (val) {
if (this.allowSearchFlag && val.length > 2) { // 輸入超過兩個(gè)字符進(jìn)行檢索
this.allowSearchFlag = false
this.branchTreeData = []
this.queryParam.xPage = 1
this.queryBranchData(val)
}
}
},
queryBranchData(param, appendFlag) { // 請(qǐng)求后端數(shù)據(jù)
const cacheUrl = 'http://XXXXXXXXX.uat.cn/cache/queryParamPager'
if (!isNaN(parseInt(param)) && isFinite(param)) {
this.queryParam['xCode'] = param
} else if (param && param.trim() !== '') {
this.queryParam['xName'] = param
}
axios.post(cacheUrl, this.queryParam, {
headers: { 'Content-Type': 'application/json' },
withCredentials: false
}).then(res => {
if (res.data.code === 200 && res.data.data.list.join() !== '') { // 如果后端返回?cái)?shù)據(jù)有值
if (appendFlag) { // 是否拼接數(shù)據(jù)
this.branchTreeData = this.branchTreeData.concat(res.data.data.list)
} else {
this.branchTreeData = res.data.data.list
}
this.allowSearchFlag = true
this.loading = false
}
}).catch(err => console.error(`獲取機(jī)構(gòu)參數(shù)異常, ${err}`))
},
clearSelect() { // 清空下拉框選中的值,會(huì)向后端重新查詢第一頁的數(shù)據(jù)
this.queryParam['xCode'] = ''
this.queryParam['xName'] = ''
this.queryParam.xPage = 1
this.branchTreeData = []
this.queryBranchData()
},
focusSelect() { // 光標(biāo)觸發(fā)下拉框時(shí),如果下拉框數(shù)據(jù)為空,則向后端查詢第一頁數(shù)據(jù)
if (this.branchTreeData.join() === '') {
this.queryParam['xCode'] = ''
this.queryParam['xName'] = ''
this.queryBranchData()
}
}
}
}
</script>
<style scoped>
</style>
第四步, 在父組件中引入第三步創(chuàng)建的子組件
// 使用第三步創(chuàng)建的子組件
<branch-tree-select ref="accBranchRef" :branch-number="QueryProtocolListX1.accBranch" @setBranchNumber="setAccBranchNumber" />
// 引入子組件
import BranchTreeSelect from '@/components/BranchTreeSelect'
components: {
BranchTreeSelect
}
mothods: {
setAccBranchNumber(val) {
// val就是子組件選中的值
}
}
以上內(nèi)容四個(gè)步驟從下面鏈接復(fù)制https://devpress.csdn.net/vue/66caf7da8f4f502e1cfda77e.html
以下內(nèi)容四個(gè)步驟從下面鏈接復(fù)制
https://www.cnblogs.com/caihongmin/p/17920859.html
自定義指令
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)聽的句柄防抖一下
const handle = debounce((e) => {
let scrollDistance = scrollWrap.scrollHeight - scrollWrap.scrollTop
// 比如此處預(yù)留6個(gè)像素的位置用于觸底
if (scrollWrap.clientHeight + 6 > scrollDistance) {
binding.value() // 觸底通知一下,外界
}
}, 170)
// 綁定監(jiān)聽滾動(dòng)事件
scrollWrap?.addEventListener('scroll', handle)
// 把監(jiān)聽的句柄掛載到元素身上便于解綁時(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è)分頁接口
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ā)請(qǐng)求
loadmore() {
this.pageIndex = this.pageIndex + 1
this.getOptions()
},
},
};
</script>