ElementPlus 中el-select自定义指令实现触底加载请求options数据的方法

 更新时间:2024年08月03日 11:19:43   作者:小御姐@stella  
触底时,继续向后端发请求获取下一页的数据,请求回来的数据合并给options,这篇文章主要介绍了ElementPlus 中el-select自定义指令实现触底加载请求options数据的操作方法,需要的朋友可以参考下

 1) 背景:

        老项目翻新时,发现一个下拉框数据非常多,客户呢,希望全部数据一起展示,意思就是全部数据一起返回给前端用于展示。但这会造成明显的卡顿。~~明显的不合理! QAQ!~~

   于是压力给到前端,查询资料,各种搜索,最终找到2个解决方案。
    1、在el-select下拉框中添加分页组件,让用户点击下一页下一页
    2、在el-select下拉框中数据,触底加载

 当然最终选择了第二个方案,用户体验会更好。
    由于项目中有多个地方使用到 且 可能单个页面中会用到多次,为了复用选择了自定义指令的方式去实现。

 2) 先来看看实现的效果

3) 思路

  • 触底加载,哪个元素滚动触底时加载?
    • 承装下拉框中所有元素的容器(.el-scrollbar__wrap)
  • 触底时,触发方法做什么?
    • 触底时,继续向后端发请求获取下一页的数据,请求回来的数据合并给options

4) 简单的写一下.vue文件代码

接口数据是自己用node写的

后端代码在这里:GitHub - stella99888/tao-express: Vue2+Express

```javascript
  <!-- 下拉框触底加载页面 -->
  <template>
    <div class="m-4">
      <p>第一个select</p>
      <el-select v-model="value" v-loadmore="loadmore" :teleported="false" style="width:240px">
        <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
      </el-select>
      <p>第二个select</p>
      <el-select v-model="value" v-loadmore="loadmore" :teleported="false" style="width:240px">
        <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
      </el-select>
    </div>
  </template>
<script setup>
import axios from 'axios';
import { onMounted, reactive, ref } from 'vue'
const list = ref([])
const options = ref([])
const option = ref([])
const value = ref([])
const loading = ref(false)
let pageData = reactive({
  pageIndex: 1,
  pageSize: 10
})
onMounted(() => {
  getOptions()
})
const getOptions = () => {
  axios.get(`http://localhost:9999/getSelectOptions?pageIndex=${pageData.pageIndex}&pageSize=${pageData.pageSize}`)
    .then(res => {
      console.log(res.data);
      if (res.data.length < 1) {
        ElMessage({
          message: '没有更多数据了...',
          type: "warning",
        });
      }
      const newOptions = res.data.map((item) => {
        return { value: item.name, label: item.index }
      })
      options.value.push(...newOptions)
    })
}
// 触底了,继续发请求
const loadmore = () => {
  pageData.pageIndex = pageData.pageIndex + 1
  getOptions()
}
</script>

* 注意一下:
 1. teleported属性为官网提供,是否将下拉列表插入至 body 元素,默认值为true,插入到body元素中。

>  这是插入body中的

> 这是不插入body中的(可以对比下)

 2. 我们需要将其插入body元素中吗?如果是单个页面中只出现一个,那影响不大;如果是多个,我们要选中该元素时就很不方便了。 
 3. 且,我们这边使用的是自定义指令的方式,指令在el-select元素上,teleported为false,不插入body时,正好可以在自定义指令中使用el.querySelector('.el-scrollbar__wrap')获取滚动的元素。

5) 自定义指令

前端代码在这里:GitHub - wwaini/tao-vue3 at release240625

// src/directives/loadmore/index.js
import { debounce } from "lodash";
export default {
  mounted(el, binding) {
    // 不插入body时,以下方式可获取元素
    // 插入body时,需要以document.querySelector('.el-scrollbar__wrap')获取
    let scrollWrap = el.querySelector('.el-scrollbar__wrap')
    // 把监听的方法防抖一下
    const handle = debounce((e) => {
      let scrollDistance = scrollWrap.scrollHeight - scrollWrap.scrollTop
      // 比如此处预留10个像素的位置用于触底
      if (scrollWrap.clientHeight + 10 > scrollDistance) {
        binding.value() // 触底通知一下,外界
      }
    }, 170)
    // 绑定监听滚动事件
    scrollWrap?.addEventListener('scroll', handle)
    // 方法挂载到元素身上便于解绑时使用
    el._hanlde = handle
  },
  unmounted(el, binding) {
    let scrollWrap = document.querySelector('.el-scrollbar__wrap')
    scrollWrap?.removeEventListener('scroll', el._hanlde)
    el._hanlde = null
  }
}
// directives/index.js
import loadmore from "./loadmore"
// 自定义指令对象,用于遍历注册
const directives = {
    loadmore
}
// 批量注册指令并暴露到main.js中去便于注册
export default {
  install(app) {
    Object.keys(directives).forEach((key) => {
      app.directive(key, directives[key])
    })
  }
}
// main.js
import { createApp } from 'vue';
import App from './App.vue';
const app = createApp(App);
// 引入并使用自定义指令
import directive from './directives'
app.use(directive);
app.mount('#app');
// src/views/num/six.vue
  <!-- 下拉框触底加载自定义指令 -->
  <template>
    <div class="m-4">
      <p>第一个select</p>
      <el-select v-model="value" v-loadmore="loadmore" :teleported="false" style="width:240px">
        <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
      </el-select>
      <p>第二个select</p>
      <el-select v-model="value" v-loadmore="loadmore" :teleported="false" style="width:240px">
        <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
      </el-select>
    </div>
  </template>
<script setup>
import axios from 'axios';
import { onMounted, reactive, ref } from 'vue'
const list = ref([])
const options = ref([])
const option = ref([])
const value = ref([])
const loading = ref(false)
let pageData = reactive({
  pageIndex: 1,
  pageSize: 10
})
onMounted(() => {
  getOptions()
})
const getOptions = () => {
  axios.get(`http://localhost:9999/getSelectOptions?pageIndex=${pageData.pageIndex}&pageSize=${pageData.pageSize}`)
    .then(res => {
      console.log(res.data);
      if (res.data.length < 1) {
        ElMessage({
          message: '没有更多数据了...',
          type: "warning",
        });
      }
      const newOptions = res.data.map((item) => {
        return { value: item.name, label: item.index }
      })
      options.value.push(...newOptions)
    })
}
// 触底了,继续发请求
const loadmore = () => {
  pageData.pageIndex = pageData.pageIndex + 1
  getOptions()
}
</script>

到此这篇关于ElementPlus 中el-select自定义指令实现触底加载请求options数据的文章就介绍到这了,更多相关el-select触底加载请求options数据内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • element中TimePicker时间选择器禁用部分时间(显示禁用到分钟)

    element中TimePicker时间选择器禁用部分时间(显示禁用到分钟)

    这篇文章主要介绍了element中TimePicker时间选择器禁用部分时间(显示禁用到分钟),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • 前端vue滚动条滚动监听问题成功解决办法

    前端vue滚动条滚动监听问题成功解决办法

    在Vue中监听滚动事件可以通过使用指令或者自定义事件来实现,这篇文章主要给大家介绍了关于前端vue滚动条滚动监听问题成功解决的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-09-09
  • Vue过滤器,生命周期函数和vue-resource简单介绍

    Vue过滤器,生命周期函数和vue-resource简单介绍

    这篇文章主要介绍了Vue过滤器,生命周期函数和vue-resource简单介绍,帮助大家更好的理解和使用vue,感兴趣的朋友可以了解下
    2021-01-01
  • 解决vue的router组件component在import时不能使用变量问题

    解决vue的router组件component在import时不能使用变量问题

    这篇文章主要介绍了解决vue的router组件component在import时不能使用变量问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • vue3.0 搭建项目总结(详细步骤)

    vue3.0 搭建项目总结(详细步骤)

    这篇文章主要介绍了vue3.0 搭建项目总结(详细步骤),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • 在vue中使用jsx语法的使用方法

    在vue中使用jsx语法的使用方法

    这篇文章主要介绍了在vue中使用jsx语法的使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • VUE递归树形实现多级列表

    VUE递归树形实现多级列表

    这篇文章主要为大家详细介绍了VUE递归树形实现多级列表,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • vue input输入框模糊查询的示例代码

    vue input输入框模糊查询的示例代码

    本篇文章主要介绍了vue input输入框模糊查询的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • 使用vite创建vue3项目的详细图文教程

    使用vite创建vue3项目的详细图文教程

    创建Vue3项目有两种常见的方式,一种是想vue2版本一样使用脚手架工具创建,创建vue3项目的脚手架必须是4版本以上的,另一种方法就是使用vite创建,这篇文章主要给大家介绍了关于如何使用vite创建vue3项目的相关资料,需要的朋友可以参考下
    2022-11-11
  • vue3使用el-radio-group获取表格数据无法选中问题及解决方法

    vue3使用el-radio-group获取表格数据无法选中问题及解决方法

    这篇文章主要介绍了vue3使用el-radio-group获取表格数据无法选中问题及解决方法,本文给大家介绍的非常详细,需要的朋友可以参考下
    2024-05-05

最新评论