实现思路:利用选择框自带的@popupScroll事件实现滚动回调往渲染数据不断添加新的数据,这里需要注意的是在通过文本查询数据是原始数据就不是接口返回的是数据了,需要通过文本筛选出符合要求的所有数据,然后再进行滚动添加新数据的操作。
<a-col :md="8" :sm="24">
<a-form-item label="剪辑">
<a-select
show-search
option-filter-prop="children"
:filter-option="(input, option) => option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0"
style="width: 100%"
v-model="queryParam.createUser"
placeholder="请选择剪辑"
:allowClear="true"
@search="handleSearch"
@popupScroll="handlePopupScroll"
@select="handleSelect">
<a-select-option
v-for="(item, index) in renderData"
:key="index"
:value="item.value">
{{item.name}}
</a-select-option>
</a-select>
</a-form-item>
</a-col>
-
@search="handleSearch" 根据输入内容查询所有数据,筛选出符合条件的对象再渲染在选择框选项中,重复滚动加载。
-
@popupScroll="handlePopupScroll"这个是antd选择框自带的事件,但在选择框中滚动时会触发回调函数,这样我们就可以在回调函数时往渲染列表中添加新的渲染数据。
-
@select="handleSelect" 这个是当我们选中选项时触发,选中时我们得判断我们查询参数是否存在,存在的话得筛选出查询的数据并且将该数据放在renderData第一个位置(未做处理会出现找不到该数据,导致直接显示key或者value值)
import debounce from 'lodash/debounce' //处理防抖,导致频繁触发事件
export default {
data(){
return{
createUserData: [],//存放原始数据
renderData:[],//以渲染的下拉列表
LOAD_LEN:20,
searchVal: '', // 搜索的内容
filterDataList: [], // 过滤的数据列表 -- 从dataList中过滤出含搜索内容的数据
}
},
created(){
this.getOperateData()//调接口获取数据
},
methods:{
getOperateData() {
powerSelector({ org_id: 2881, status: 1 }).then((res) => {
//获取所有数据
this.createUserData = res.data
//直接截取最前面的部分数据
this.renderData=res.data.slice(0,this.LOAD_LEN)
}),
},
// 文本框中的值变化时执行
handleSearch (val){
this.searchVal=val
let filterList=[]
if(val){
filterList=this.createUserData.filter(item=>item.name.indexOf(val)>-1)
}else{
filterList=this.createUserData
}
this.filterDataList=filterList;
this.renderData=filterList.length<this.LOAD_LEN?filterList:filterList.slice(0,this.LOAD_LEN)
},
// 选择器滚动后进行加载数据
handlePopupScroll: debounce(function(){
//通过文本框输入内容判断渲染的数据是筛选的还是直接获取的
if(this.searchVal===''){
this.loadMoreData(this.createUserData)
}else{
this.loadMoreData(this.filterDataList)
}
},400),
// 加载更多数据到select框
loadMoreData (dataList) {
let renderLen=this.renderData.length
let totalLen=dataList.length;
let addList=[]
//判断已经渲染的数据长度和将要渲染的总长度
if(renderLen<totalLen){
if(renderLen+this.LOAD_LEN<=totalLen){
addList=dataList.slice(renderLen,renderLen+this.LOAD_LEN)
}else{
addList=dataList.slice(renderLen,totalLen)
}
this.renderData=(this.renderData).concat(addList)
}
},
// 被选中时调用,参数为选中项的 value (或 key) 值
handleSelect (val) {
//判断筛选文本是否存在,存在就需要把该数据放到渲染的开头,避免出现选中数据在渲染数据中不存在。
if(this.searchVal){
// 从所有数据中过滤出选中的数据
const selectList=(this.createUserData).filter(item=>item.value===val)
const restList=(this.createUserData).filter(item=>item.value!==val)
this.renderData=selectList.concat(restList.slice(0,this.LOAD_LEN))
this.searchVal=''
}
},
}
}
由于项目会大量出现以上情况,可以使用局部混入实现复用
import debounce from 'lodash/debounce'
// 调接时获取原始数据
// this.originDataList=res.data
// this.name='name'
// this.value='value'
// this.renderData=res.data.slice(0,this.LOAD_LEN)
/**
* 给选择框添加事件
@search="handleSearch"
@popupScroll="handlePopupScroll"
@select="handleSelect"
*/
/**选择账户
* import selectOption from '@/utils/selectOption'
* this.originDataList=res.data
this.selectName='advertiserName'
this.selectValue='advertiserId'
this.renderData=(res.data).slice(0,this.LOAD_LEN)
*/
const selectOption={
data(){
return {
renderData:[], //以渲染的下拉列表
originDataList:[], //原始数据
LOAD_LEN:20, //初次加载数据长度
searchVal: '', // 搜索的内容
filterDataList: [], // 过滤的数据列表 -- 从dataList中过滤出含搜索内容的数据
selectName:'', // 显示的选项
selectValue:'', // 获取的值
}
},
methods:{
// 文本框中的值变化时执行
handleSearch (val){
this.searchVal=val
let filterList=[]
if(val){
filterList=this.originDataList.filter(item=>item[this.selectName].indexOf(val)>-1||item[this.selectValue].indexOf(val)>-1)
}else{
filterList=this.originDataList
}
this.filterDataList=filterList;
console.log();
this.renderData=filterList.length<this.LOAD_LEN?filterList:filterList.slice(0,this.LOAD_LEN)
},
// 选择器滚动后进行加载数据
handlePopupScroll: debounce(function(){
console.log('gundon');
if(this.searchVal===''){
this.loadMoreData(this.originDataList)
}else{
this.loadMoreData(this.filterDataList)
}
},400),
// 加载更多数据到select框
loadMoreData (dataList) {
let renderLen=this.renderData.length
let totalLen=dataList.length;
let addList=[]
if(renderLen<totalLen){
if(renderLen+this.LOAD_LEN<=totalLen){
addList=dataList.slice(renderLen,renderLen+this.LOAD_LEN)
}else{
addList=dataList.slice(renderLen,totalLen)
}
this.renderData=(this.renderData).concat(addList)
}
},
// 被选中时调用,参数为选中项的 value (或 key) 值
handleSelect (val) {
if(this.searchVal){
// 从所有数据中过滤出选中的数据
const selectList=(this.originDataList).filter(item=>item[this.selectValue]===val)
const restList=(this.originDataList).filter(item=>item[this.selectValue]!==val)
this.renderData=selectList.concat(restList.slice(0,this.LOAD_LEN))
this.searchVal=''
}
},
},
}
export default selectOption