当前位置: 首页 > article >正文

el-select滚动获取下拉数据;el-select滚动加载

el-select下拉获取数据

    • 1.解决问题
    • 2.封装MyScrollSelect组件
    • 3.使用MyScrollSelect组件

1.解决问题

场景:下拉数据量过大,后端提供一个分页查询接口;需要每次滚动加载下一页的下拉数据
且单选的状态,需要支持回显,通过name名称查询回显;–本文已包含
如果是多选回显,可以让后端提供一个根据idList能反向找到对应id的下拉集合的接口;–可自己试试

2.封装MyScrollSelect组件

<template>
  <div>list长度:{{ list.length }}</div>
  <div>$attrs:{{ $attrs }}</div>
  <el-select @change="changeVal" v-bind="$attrs" :remote-method="remoteMethod" style="width: 100%">
    <div v-infinite-scroll="loadMore" style="overflow: hidden">
      <el-option v-for="item in list" :key="item[valueKey]" :label="item[labelKey]" :value="item[valueKey]" />
      <!-- 下拉底部加载提示 -->
      <div v-if="loading" class="loading-text">加载中...</div>
    </div>
  </el-select>
</template>

<script setup >
import { ref, watch, onMounted } from "vue"
import { debounce } from "lodash"

const emit = defineEmits(['update:searchName']);

const props = defineProps({
  // v-model绑定值不为空时传递初始数据列表
  initialOptions: {
    type: Array,
    default: () => []
  },
  // 传入对应的列表加载api
  methods: {
    type: Function,
    required: true // 或者 true,取决于它是否必须被传递
  },
  // 传入查询关键字
  searchKey: {
    type: String,
    default: ""
  },
  // 所选key对用name
  searchName: {
    type: String,
    default: undefined
  },
  labelKey: {
    type: String,
    default: "name"
  },
  valueKey: {
    type: String,
    default: "id"
  },
  // 查询的其他参数
  queryData: {
    type: Object,
    default: () => { }
  },
})

const isMounted = ref(false)
const loading = ref(false)

const list = ref([]) // 选项列表
const queryFrom = ref({
  pageNum: 1,
  totalPage: 1,
  pageSize: 20
})

// 自定义远程搜索方法
const remoteMethod = (query) => {
  queryFrom.value.pageNum = 1
  list.value = []
  queryFrom.value[props.searchKey] = query
  queryFrom.value = { ...queryFrom.value, ...props.queryData }
  getList()
}

// 调用props.methods获取下拉数据
const getList = () => {
  loading.value = true
  props.methods(queryFrom.value).then(res => {
    console.log('%c【' + 'res' + '】打印', 'color:#fff;background:#0f0', res)
    list.value = [...list.value, ...res.records]
    queryFrom.value.totalPage = Math.ceil(res.total / 20) // 计算总页数 不是总数
  }).finally(() => {
    loading.value = false
  })
}

// 无限滚动触底加载
const loadMore = debounce(() => {
  if (queryFrom.value.pageNum >= queryFrom.value.totalPage || loading.value) return
  queryFrom.value.pageNum++
  getList()
}, 200)

// 根据id回显name
const changeVal = (e) => {
  list.value.forEach(ele => {
    if (ele[props.valueKey] === e) {
      emit('update:searchName', ele[props.labelKey])
    }
  })
}

// 监听 initialOptions 的变化,用于加载初始值
watch(
  () => props.initialOptions,
  newVal => {
    // 如果 modelValue 中的值还未加载到选项中,加载这些数据
    if (newVal && newVal.length > 0) {
      list.value.push(...props.initialOptions)
    }
  },
  { immediate: true }
)

onMounted(() => {
  isMounted.value = true
  // 获取初始数据

  if (props.searchName) {
    remoteMethod(props.searchName) // 根据name回显
  } else {
    getList()
  }
})
</script>
<style scoped>
.loading-text {
  padding: 5px;
  text-align: center;
  color: #999;
  font-size: 12px;
}
</style>

3.使用MyScrollSelect组件

<template>
  <div class="page-view wbg pall">
    <pre>{{ form }}</pre>

    <div style="margin-top: 50px">多选:只能存id</div>
    <MyScrollSelect
      v-if="isMounted"
      ref="reviewStageRef"
      v-model="form.idList1"
      :placeholder="'滚动加载或搜索-单选'"
      clearable
      filterable
      remote
      collapse-tags
      collapse-tags-tooltip
      multiple
      :initialOptions="initialOptions"
      :methods="getDeviceNameListApi"
      searchKey="terminalDeviceName"
      valueKey="id"
      labelKey="terminalDeviceName"
    />

    <div style="margin-top: 50px">单选:可存id和name 根据name可回显</div>
    <MyScrollSelect
      v-if="isMounted"
      ref="reviewStageRef"
      v-model="form.terminalDeviceId"
      v-model:searchName="form.terminalDeviceName"
      :placeholder="'滚动加载或搜索-单选'"
      clearable
      filterable
      remote
      :initialOptions="initialOptions"
      :methods="getDeviceNameListApi"
      searchKey="terminalDeviceName"
      valueKey="id"
      labelKey="terminalDeviceName"
    />
  </div>
</template>

<script setup>
import { onMounted, ref } from 'vue'
import { getDeviceNameListApi } from "@/api/ipManagement.js" // 后端获取下拉分页接口

defineOptions({
  name: 'FactorySiteAddressLedger'
})

const isMounted = ref(false)
const form = ref({
  idList1: [], // 多选参数

  terminalDeviceId: '710241160000004443', // 单选参数
  terminalDeviceName: '益海电厂网监工作站',
})

const reviewStageRef = ref(null)

const initialOptions = ref([]) // 初始下拉数据

onMounted(() => {
  isMounted.value = true
})
</script>
<style lang="scss" scoped></style>

http://www.kler.cn/a/561495.html

相关文章:

  • 【云原生实战】DevOps基础与实战项目
  • 浅谈HTTP及HTTPS协议
  • 全域旅游景区导览系统:赋能智慧旅游生态,破解行业核心难题
  • AWS CLI将读取器实例添加到Amazon Aurora集群
  • AI大模型-提示工程学习笔记17—程序辅助语言模型
  • 博途V16画面管理、用户管理与文本和图形列表
  • 希尔排序:突破插入排序的局限
  • MongoDB 数据库简介
  • 什么是可重入,什么是可重入锁?它用来解决什么问题?
  • 使用DeepSeek/ChatGPT等AI工具辅助编写wireshark过滤器
  • 网卡驱动架构以及源码分析
  • 2011-2019年各省15岁及以上文盲人口数数据
  • 【redis】数据类型之Bitfields
  • conda、anaconda、pip、pytorch、tensorflow有什么区别?
  • MATLAB学习之旅:图像处理与计算机视觉应用
  • django filter 不等于
  • 大厂数据仓库数仓建模面试题及参考答案
  • vue2项目打包后js文件过大, 首次加载缓慢
  • AI工具生成答案格式整理与保证生成文献真实性办法
  • 星环科技推出DeepSeek全场景解决方案:即开即用、企业级部署、端侧智能三位一体