SearchSelect.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. <template>
  2. <el-select ref="selectDropRef" :multiple-limit="limit" @change="changeSelect" multiple v-model="value" filterable popper-class="custom-dropdown" remote reserve-keyword :remote-method="remoteMethod" remote-show-suffix clearable placeholder="请选择适用企业">
  3. <div class="optionBox" infinite-scroll-delay="500" infinite-scroll-distance="20" v-infinite-scroll="load">
  4. <template v-if="optionsV.length">
  5. <el-option v-for="item in optionsV" :key="item.value" :label="item.cpyName" :value="item.cpyid"></el-option>
  6. </template>
  7. <template v-for="item in options" :key="item.cpyid">
  8. <el-option v-if="!isOptionsV(item.cpyid)" :label="item.cpyName" :value="item.cpyid"></el-option>
  9. </template>
  10. </div>
  11. </el-select>
  12. </template>
  13. <script setup lang="ts">
  14. import { getEnterpriseDetail, getEnterpriseList } from '@/api/cdt/menus'
  15. import { propTypes } from '@/utils/propTypes';
  16. // 防抖
  17. import { debounce } from 'lodash';
  18. const props = defineProps({
  19. modelValue: propTypes.any.def([]),
  20. params: {
  21. type: Object,
  22. default: () => ({})
  23. },
  24. limit: {
  25. type: Number,
  26. default: 0
  27. }
  28. })
  29. const emit = defineEmits(['change', 'update:modelValue', 'changeItem'])
  30. const value = ref<string[]>([])
  31. const options = ref([])
  32. const optionsV = ref([])
  33. const total = ref(0)
  34. const selectDropRef = ref(null)
  35. const queryParams = ref({
  36. pageSize: 10,
  37. pageNum: 1,
  38. cpyName: '',
  39. })
  40. const getList = async (hasRx = true) => {
  41. if (hasRx) {
  42. queryParams.value.pageNum = 1
  43. options.value = []
  44. }
  45. const res = await getEnterpriseList({ ...queryParams.value, ...props.params })
  46. total.value = res.total;
  47. if (hasRx) {
  48. options.value = res.rows
  49. } else {
  50. options.value = options.value.concat(res.rows)
  51. }
  52. }
  53. const remoteMethod = (text: string) => {
  54. if (text) {
  55. queryParams.value.cpyName = text
  56. selectSearch()
  57. }
  58. }
  59. const load = () => {
  60. if (options.value.length < total.value) {
  61. queryParams.value.pageNum++
  62. getList(false)
  63. }
  64. }
  65. const changeSelect = (val: string[]) => {
  66. const itemInfo = options.value.filter(item => val.includes(item.cpyid))
  67. emit('update:modelValue', val)
  68. emit('change', val)
  69. emit('changeItem', itemInfo)
  70. }
  71. // 判断是否在optionsV
  72. const isOptionsV = (val: string) => {
  73. return optionsV.value.some((item) => item.cpyid === val)
  74. }
  75. // 获取当前id对应的企业信息
  76. const selectSearch = debounce(() => {
  77. getList()
  78. }, 500)
  79. // 根据values获取下拉框的options
  80. const getOptions = async (values: string[]) => {
  81. if (!values.length) {
  82. return
  83. }
  84. values.forEach(async (item) => {
  85. if ([...optionsV.value, ...options.value].find((v) => v.cpyid === item)) {
  86. return
  87. }
  88. const res = await getEnterpriseDetail(item)
  89. res?.data && optionsV.value.push(res.data)
  90. })
  91. }
  92. onMounted(() => {
  93. getList()
  94. nextTick(() => {
  95. // 获取下拉框的dom
  96. const dropdown = document.querySelector('.custom-dropdown .el-select-dropdown__wrap');
  97. dropdown.addEventListener('scroll', () => {
  98. if (dropdown.scrollTop + dropdown.clientHeight >= dropdown.scrollHeight) {
  99. // 在这里执行你的操作
  100. load()
  101. }
  102. });
  103. });
  104. })
  105. watch(() => props.modelValue, (val) => {
  106. value.value = val
  107. getOptions(val)
  108. }, { immediate: true })
  109. </script>