• element plus封装el-select添加后缀图标并添加远程搜索和对话框功能


    当提交的表单Form需要填某个实体的外键ID时,当然不可能使用el-input组件,这个适合提交字符串,然后用户又不可能记住某个引用的外键ID,这时候使用el-select还是必要的。

    el-select组件一般都作为下拉选择框使用,但仅在数据量少时,比较实用,比如性别的选择:男女。

    但当需要选择的数据成千上万时,就不太适用了(不可能拉一长串数据)。这就需要对其进行再改造封装。

    在这里插入图片描述
    在这里插入图片描述
    上述实现了两个效果,一个是通过远程搜索数据,一个是打开对话框筛选数据。

    思路是在el-select后边再加一个icon图标,然后添加上阴影,并隐藏suffix-icon图标和自带的阴影,伪装成一个合体的组件。

    这个组件我折腾了好久,之前想用自带的suffix-icon实现,谁知道图标Component是给属性赋值的,并不是子组件。不能给el-select传递数据,所以失败了。。。

    所以想到了这么一个方法。

    当用户记得需要选择的数据时,直接关键字查询出来即可。当用户不记得有哪些数据时,点击搜索图标打开对话框浏览分页数据。

    实现代码如下:

    <template>
      <div class="custom-select">
        <el-select v-model="innerValue" multiple filterable remote reserve-keyword :remote-method="remoteMethod"
          :multiple-limit="limit" :loading="loading" @change="change"  tag-type="">
          <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
        el-select>
        <div class="custom-icon">
          <div class="custom-icon__wrapper">
            <font-awesome-icon icon="search" @click="clickMethod" />
          div>
        div>
      div>
    template>
    <script lang="ts" setup>
    import { reactive, ref, onMounted, computed, watch } from 'vue'
    
    import { queryBill } from '@/api/lcdp/bill.js'
    
    const props = defineProps({
      //远程搜索的方法
      searchMethod: {
        type: Function,
        default: () => { }
      },
      //显示label标签的方法
      showMethod: {
        type: Function,
        default: () => { }
      },
      //多选限制数量
      limit: {
        type: Number,
        default: 1
      },
      //父组件传递的值
      value: {
        type: Number || Array || String,
        defalt: 1
      }
    })
    const options = ref<ListItem[]>([])
    const innerValue = ref<Number[] | String[]>([])
    const loading = ref(false)
    
    interface ListItem {
      value: string
      label: string
    }
    // 监听父组件传递的值的变化
    watch(
      () => props.value,
      async () => {
        if (props.value == null) {
          innerValue.value = []
        }
        if (typeof props.value === 'number') {
          innerValue.value = [props.value]
          const response = await props.showMethod(innerValue.value)
          options.value = response.data
        }
      }
    )
    // 初始化父组件传递的值
    onMounted(async () => {
      if (props.value == null) {
        innerValue.value = []
      }
      if (typeof props.value === 'number') {
        innerValue.value = [props.value]
        const response = await props.showMethod(innerValue.value)
        options.value = response.data
      }
    })
    
    
    
    /**
     * 通过关键词查询选择框列表
     * @param query 查询参数
     */
    const remoteMethod = async (query: string) => {
      if (query) {
        loading.value = true
        const response = await props.searchMethod({ q: query })
        loading.value = false
        options.value = response.data
      } else {
        options.value = []
      }
    }
    //...省略开启对话框逻辑
    script>
    <style lang="scss" scoped>
    //将阴影和圆角去掉
    ::v-deep(.el-input__wrapper) {
      border-radius: 0;
      box-shadow: 0 0 0 0;
    }
    //给边框添加阴影,并调整搜索框位置
    .custom-select {
      display: inline-block;
      box-shadow: 0 0 0 1px var(--el-input-border-color, var(--el-border-color));
      .custom-icon {
        display: inline-block;
        color: var(--el-input-icon-color, var(--el-text-color-placeholder));
        vertical-align: middle;
        cursor: pointer;
        .custom-icon__wrapper {
          padding: 1px 11px;
        }
      }
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113

    最终这样一个支持远程搜索,还能打开对话框分页查询数据的组件就封装好了。

  • 相关阅读:
    三万字盘点Spring/SpringBoot的那些常用扩展点
    C++个人财务管理系统
    健康与福祉:心理健康和身体健康的重要性
    关于MP3文件中找不到TAG标签的问题
    地理标志农产品质量安全风险评估及预警研究
    Qt入门总结
    Python语言
    有趣的 Kotlin 0x0E:DeepRecursiveFunction
    React Native项目中《动画》实践应用——以“协议未勾选登录时文字左右抖动”为例
    五. 激光雷达建图和定位方案-开源SLAM
  • 原文地址:https://blog.csdn.net/qq_40610003/article/details/132925359