Antd组件中选择框数据量太大处理

实现思路:利用选择框自带的@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>
  1. @search="handleSearch" 根据输入内容查询所有数据,筛选出符合条件的对象再渲染在选择框选项中,重复滚动加载。

  2. @popupScroll="handlePopupScroll"这个是antd选择框自带的事件,但在选择框中滚动时会触发回调函数,这样我们就可以在回调函数时往渲染列表中添加新的渲染数据。

  3. @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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值