0


elementUI中el-select数据分页懒加载实现

前言

工作中使用elementUI框架时, 会经常用到下拉框展示数据,如果数据量很大会影响页面的渲染加载速度。遇到这种情况,通常后端代码会将数据做成分页查询,前端下拉框组件也要支持滑动到底部会自动加载下一页数据。话不多说,直接上代码。

正文代码

第一步,创建select-load-more.js文件

// 定义全局自定义指令
import Vue from 'vue'

const selectLazyLoad = function(Vue) {
  // el-select组件数据过多,使用翻页加载数据指令
  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转换为整数,兼容不同版本浏览器
        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中注册引入自定义指令

import selectLazyLoad from './directive/select-load-more'    //引入
Vue.use(selectLazyLoad)    // 使用自定义指令

第三步, 创建公共组件并在组件中使用自定义指令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="可根据机构ID或机构名称筛选"
    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, // 是否允许检索, 防止连续输入时未组装好数据就再次检索
      loading: false,
      queryParam: { // 查询后端所用参数对象, 可根据自己需求变更请求参数对象
        'xCode': '', // 模糊检索code
        'xName': '', // 模糊检索name
        'xParentCode': 'AYBBRNNO',
        'xType': '',
        'xFormat': 'Y',
        'xPage': 1,
        'xPageSize': 50
      }
    }
  },
  watch: {
    'currentBranchNumber': { // 选中数据改变时,调用父组件的setBranchNumber方法,并传入选中的值
      handler(val) {
        if (val) {
          this.$emit('setBranchNumber', this.currentBranchNumber.toString().split(':')[0])
        } else {
          this.$emit('setBranchNumber', '')
        }
      }
    },
    'pageNum': { // 当前页数改变时, 重新触发查询
      handler(val) {
        if (val) {
          this.queryParam.xPage = val
          this.queryBranchData('', true)
        }
      }
    }
  },
  created() { // 组件实例创建后(data和methods已经初始化完毕), 请求后端数据
    this.queryBranchData()
  },
  methods: {
    loadMoreData() { // 数据到底部继续滑动,会自动触发页数+1
      return () => {
        this.pageNum += 1
      }
    },
    onSearch(val) { // 检索功能, 后端可以支持模糊检索
      if (val) {
        if (this.allowSearchFlag && val.length > 2) { // 输入超过两个字符进行检索
          this.allowSearchFlag = false
          this.branchTreeData = []
          this.queryParam.xPage = 1
          this.queryBranchData(val)
        }
      }
    },
    queryBranchData(param, appendFlag) { // 请求后端数据
      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() !== '') { // 如果后端返回数据有值
          if (appendFlag) { // 是否拼接数据
            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(`获取机构参数异常, ${err}`))
    },
    clearSelect() { // 清空下拉框选中的值,会向后端重新查询第一页的数据
      this.queryParam['xCode'] = ''
      this.queryParam['xName'] = ''
      this.queryParam.xPage = 1
      this.branchTreeData = []
      this.queryBranchData()
    },
    focusSelect() { // 光标触发下拉框时,如果下拉框数据为空,则向后端查询第一页数据
      if (this.branchTreeData.join() === '') {
        this.queryParam['xCode'] = ''
        this.queryParam['xName'] = ''
        this.queryBranchData()
      }
    }
  }
}
</script>

<style scoped>

</style>

第四步, 在父组件中引入第三步创建的子组件

// 使用第三步创建的子组件
<branch-tree-select ref="accBranchRef" :branch-number="QueryProtocolListX1.accBranch" @setBranchNumber="setAccBranchNumber" />

// 引入子组件
import BranchTreeSelect from '@/components/BranchTreeSelect'

components: {
    BranchTreeSelect
}

mothods: {
    setAccBranchNumber(val) {
      // val就是子组件选中的值
    }
}

后言

这样子组件下拉框就实现了检索、分页懒加载功能,目前只是简单的实现了功能, 可能某一天会心血来潮优化下代码...

如有问题请在下方留言,我会认真的查看每一条并尽量的给予回复。谢谢观看^^

标签: elementui 前端 vue.js

本文转载自: https://blog.csdn.net/Damon_Cheung/article/details/127999724
版权归原作者 Damon快点跑 所有, 如有侵权,请联系我们删除。

“elementUI中el-select数据分页懒加载实现”的评论:

还没有评论