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

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.dtcms.com/a/35541.html

相关文章:

  • 【信息系统项目管理师-案例真题】2011上半年案例分析答案和详解
  • 使用python接入腾讯云DeepSeek
  • 数据类型转换
  • 项目范围管理--从规划到控制项目范围的核心思想
  • 多弹协同末制导律设计
  • C++与Python实现LiDAR点云投影对比:关键差异与易错点详解
  • CAESAR II 14管道应力和柔性分析软件
  • 【WSL2】 Ubuntu20.04 GUI图形化界面 VcXsrv ROS noetic Vscode 配置
  • Scratch032(百发百中)
  • Kafka RecordTooLargeException问题解决
  • 第三章 语言基础
  • 2025年信息科学与工程学院科协机器学习介绍——机器学习基本模型介绍
  • 智慧后勤的消防管理:豪越科技为安全护航
  • TDengine数据订阅新手入门避坑指南1/3
  • 2025/2/17--2/23学习笔记(week1)_C语言
  • C语言进阶习题【3】(5 枚举)——找单身狗2进阶版本
  • 【前沿探索篇七】【DeepSeek自动驾驶:端到端决策网络】
  • AWS Bedrock平台引入DeepSeek-R1 模型,推动深度学习
  • 网站搭建wp
  • unity学习51:所有UI的父物体:canvas画布
  • AI大模型趣味实战专栏 预告篇
  • 文件上传-黑名单关键字绕过
  • 用C/C++绘制跳动的爱心:从数学方程到动画实现
  • 数据安全_笔记系列02:国密算法(商用密码算法)详解
  • JavaScript querySelector()、querySelectorAll() CSS选择器解析(DOM元素选择)
  • MySQL数据库——常见慢查询优化方式
  • 基于STM32单片机设计的宠物喂食监控系统
  • Zap:Go 的高性能日志库
  • Linux故障排查和性能优化面试题及参考答案
  • 计算机毕业设计SpringBoot+Vue.js古典舞在线交流平台(源码+文档+PPT+讲解)