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

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

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

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


上述实现了两个效果,一个是通过远程搜索数据,一个是打开对话框筛选数据。

html 复制代码
<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>

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

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

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

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

相关推荐
code_YuJun13 分钟前
corepack 作用
前端
千寻girling14 分钟前
Koa.js 教程 | 一份不可多得的 Node.js 的 Web 框架 Koa.js 教程
前端·后端·面试
全栈前端老曹15 分钟前
【MongoDB】Node.js 集成 —— Mongoose ORM、Schema 设计、Model 操作
前端·javascript·数据库·mongodb·node.js·nosql·全栈
code_YuJun16 分钟前
pnpm-workspace.yaml
前端
天才熊猫君19 分钟前
“破案”笔记:iframe动态加载内容后,打印功能为何失灵?
前端
五月君_36 分钟前
炸裂!Claude Opus 4.6 与 GPT-5.3 同日发布:前端人的“自动驾驶“时刻到了?
前端·gpt
Mr Xu_40 分钟前
前端开发中CSS代码的优化与复用:从公共样式提取到CSS变量的最佳实践
前端·css
低代码布道师1 小时前
Next.js 16 全栈实战(一):从零打造“教培管家”系统——环境与脚手架搭建
开发语言·javascript·ecmascript
鹏北海-RemHusband1 小时前
从零到一:基于 micro-app 的企业级微前端模板完整实现指南
前端·微服务·架构
LYFlied1 小时前
AI大时代下前端跨端解决方案的现状与演进路径
前端·人工智能