优化表单交互:在 el-select 组件中嵌入表格显示选项
介绍了一种通过 el-select 插槽实现表格样式数据展示的方案,可更直观地辅助用户选择。支持列配置、行数据绑定及自定义搜索,简洁高效,适用于复杂选择场景。完整代码见GitHub 仓库。
背景
在进行业务开发选择订单时,如果单纯的根据单号是无法编写是哪一条订单的,这个时候就可以通过表格的方式去展示这条订单的其他信息,辅助用户分辨出订单,不用再去查,更快速、更友好。
效果如下:

实现
环境与依赖
- node 22
- vue 3
- element-plus
思路
原理很简单,利用插槽。
虽然通过 el-table 可以实现表格效果,但对这种简单需求来说过于臃肿。而直接使用原生 table 标签结构实现太过于繁琐,不便于实现遍历 el-option。
<el-select><!-- 表头,遍历 --><!-- 表体,遍历 --><el-option><!-- 行数据,遍历 --></el-option>
</el-select>
因此,我采用列表结构实现,结合 CSS 美化出表格效果。具体做法是遍历「列配置」生成表头,再遍历「options」生成行数据。
<el-select ref="inputRef" v-model="selectValue"clearablefilterable:placeholder="placeholder" :disabled="disabled" :filter-method="filterMethod" @change="handleChange"
><!-- 表头 --><ul class="select-ul"><li v-for="column in columnConfig" :key="column.label">{{ column.label }}</li></ul><el-option v-for="item in showOptions" :key="item[keyNameCom]" :value="item[valueName]"><ul class="select-ul select-ul-data"><li v-for="column in columnConfig" :key="column.label">{{ item[column.prop] }}</li></ul></el-option>
</el-select>
其中,el-option 的数据绑定属性名默认是 id,可通过配置修改。同时,遍历 key 属性支持自定义,若为空则默认使用 value 属性名,减少额外数据处理。
如何使用
一个简单演示。
options:行数据columnConfig:列配置
template 结构和 js 部分如下:
<BaseTableSelect v-model="selectValue" :options="options" :columnConfig="columnConfig"
>
</BaseTableSelect>
const options = ref([{id: "213", department: '古典风格号', createTime: '2024-12-23', place: '学校'},{id: "546", department: '都听好', createTime: '2024-12-23', place: '家里'},{id: "345", department: '按时到岗', createTime: '2024-12-23', place: '医院'}
])const columnConfig = ref([{label: '单号', prop: 'id'},{label: '部门', prop: 'department'},{label: '时间', prop: 'createTime'},{label: '地点', prop: 'place'},
])
自定义全表格搜索

组件 el-select 默认的搜索功能只会根据 label 属性的值去搜索,在表格展示的场景下并不符合,因此需要用到 filter-method 自定义搜索方法属性。
初步简单实现可使用 JSON.stringify() 将选项对象转为字符串,并检测是否包含搜索关键词:
const filterMethod = queryString => {showOptions.value = props.options.filter(item => (JSON.stringify(item).includes(queryString) ? true : false))
}
不过,这种方式会将未展示的属性也纳入搜索,导致结果不准确。因此,优化后的搜索方法仅匹配已展示的列数据:
const filterMethod = queryString => {if (!queryString) {showOptions.value = props.options;return;}showOptions.value = props.options.filter(item => {// 针对每个要过滤的列进行判断return props.columnConfig.some(config => {const propValue = item[config.prop];// 将属性值转换为字符串并检查是否包含查询字符串return propValue && propValue.toString().includes(queryString);});});
}
扩展
本文提供的是基础实现。如果需要进一步功能扩展,例如控制搜索功能 (filterable) 或其他交互行为,可通过额外配置实现。但基础版本已满足我的需求,便不写太多不利于阅读代码。
组件代码
仓库:🔗 el-select-table-option
<template><el-select ref="inputRef" v-model="selectValue"clearablefilterable:placeholder="placeholder" :disabled="disabled" :filter-method="filterMethod" @change="handleChange"><!-- 表头 --><ul class="select-ul"><li v-for="column in columnConfig" :key="column.label">{{ column.label }}</li></ul><el-option v-for="item in showOptions" :key="item[keyNameCom]" :value="item[valueName]"><ul class="select-ul select-ul-data"><li v-for="column in columnConfig" :key="column.label">{{ item[column.prop] }}</li></ul></el-option></el-select>
</template><script setup>
import { ref, reactive, onMounted, computed, watch, nextTick } from 'vue'defineOptions({name: 'BaseTableSelect'
})const emit = defineEmits(['update:modelValue', 'keyup-enter', 'focus', 'change'])const props = defineProps({modelValue: null,disabled: {type: Boolean,default: false},placeholder: {type: String,default: '请选择'},/* 列配置 */columnConfig: {type: Array,default(rawProps) {return []}},options: {type: Array,default(rawProps) {return []}},valueName: {type: String,default: 'id'},keyName: {type: String,default: ''}
})const selectValue = computed({get: () => props.modelValue,set: val => {emit('update:modelValue', val)}
})// 实际 keyName
// 优先使用 keyName,keyName 为空时,使用 valueName
const keyNameCom = computed(() => {return props.keyName !== '' ? props.keyName : props.valueName
})const handleChange = val => {emit('change', val)
}// ref
const inputRef = ref(null)// 渲染用的options
const showOptions = ref(props.options)
watch(() => props.options,newValue => {showOptions.value = newValueselectValue.value = ''},
)
// 筛选
const filterMethod = queryString => {if (!queryString) {showOptions.value = props.options;return;}showOptions.value = props.options.filter(item => {// 针对每个要过滤的列进行判断return props.columnConfig.some(config => {const propValue = item[config.prop];// 将属性值转换为字符串并检查是否包含查询字符串return propValue && propValue.toString().includes(queryString);});});
}// 得到焦点
const getFocus = () => {nextTick(() => {inputRef.value.focus()})
}defineExpose({getFocus
})
</script><style lang="scss" scoped></style>
<style scoped lang="scss">
.select-ul {padding-right: 0;list-style: none;display: flex;justify-content: space-between;text-align: center;padding-inline-start: 0;padding: 0 20px;> li {display: inline-block;width: 100px;// margin: 6px;overflow: hidden;text-overflow: ellipsis;}
}
.el-select-dropdown__item {padding: 0;
}
</style>
属性
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| disabled | 是否禁用 | boolean | false |
| placeholder | 请选择 | string | ‘请选择’ |
| columnConfig | 列配置,[{label: ‘’, prop: ‘’}] | array | [] |
| options | 选项 | array | [] |
| valueName | 选项值的属性名 | string | ‘id’ |
| keyName | 遍历选项时的 key | string | ‘’ |
参考
无
首发地址:https://blog.xchive.top/2024/optimizing-form-interactions-embedding-table-display-options-in-el-select-components.html
相关文章:
优化表单交互:在 el-select 组件中嵌入表格显示选项
介绍了一种通过 el-select 插槽实现表格样式数据展示的方案,可更直观地辅助用户选择。支持列配置、行数据绑定及自定义搜索,简洁高效,适用于复杂选择场景。完整代码见GitHub 仓库。 背景 在进行业务开发选择订单时,如果单纯的根…...
每日一题 LCR 079. 子集
LCR 079. 子集 主要应该考虑遍历的顺序 class Solution { public:vector<vector<int>> subsets(vector<int>& nums) {vector<vector<int>> ans;vector<int> temp;dfs(nums,0,temp,ans);return ans;}void dfs(vector<int> &…...
cocos creator 3.8 Node学习 3
//在Ts、js中 this指向当前的这个组件实例 //this下的一个数据成员node,指向组件实例化的这个节点 //同样也可以根据节点找到挂载的所有组件 //this.node 指向当前脚本挂载的节点//子节点与父节点的关系 // Node.parent是一个Node,Node.children是一个Node[] // th…...
微信小程序底部button,小米手机偶现布局错误的bug
预期结果:某button fixed 到页面底部,进入该页面时,正常显示button 实际结果:小米13pro,首次进入页面,button不显示。再次进入时,则正常展示 左侧为小米手机第一次进入。 遇到bug的解决思路&am…...
【计组】复习题
冯诺依曼型计算机的主要设计思想是什么?它包括哪些主要组成部分? 主要设计思想: ①采用二进制表示数据和指令,指令由操作码和地址码组成。 ②存储程序,程序控制:将程序和数据存放在存储器中,计算…...
Apache Maven 标准文件目录布局
Apache Maven 采用了一套标准的目录布局来组织项目文件。这种布局提供了一种结构化和一致的方式来管理项目资源,使得开发者更容易导航和维护项目。理解和使用标准目录布局对于有效的Maven项目管理至关重要。本文将探讨Maven标准目录布局的关键组成部分,并…...
Android 功耗分析(底层篇)
最近在网上发现关于功耗分析系列的文章很少,介绍详细的更少,于是便想记录总结一下功耗分析的相关知识,有不对的地方希望大家多指出,互相学习。本系列分为底层篇和上层篇。 大概从基础知识,测试手法,以及案例…...
【Xbim+C#】创建圆盘扫掠IfcSweptDiskSolid
基础回顾 https://blog.csdn.net/liqian_ken/article/details/143867404 https://blog.csdn.net/liqian_ken/article/details/114851319 效果图 代码示例 在前文基础上,增加一个工具方法: public static IfcProductDefinitionShape CreateDiskSolidSha…...
IntelliJ+SpringBoot项目实战(四)--快速上手数据库开发
对于新手学习SpringBoot开发,可能最急迫的事情就是尽快掌握数据库的开发。目前数据库开发主要流行使用Mybatis和Mybatis Plus,不过这2个框架对于新手而言需要一定的时间掌握,如果快速上手数据库开发,可以先按照本文介绍的方式使用JdbcTemplat…...
利用oss进行数据库和网站图片备份
1.背景 由于网站迁移到香港云 服务器,虽然便宜,但是宿主服务器时不时重启,为了预防不可控的因素导致网站资料丢失,所以想到用OSS 备份网站数据,bucket选择在香港地区创建,这样和你服务器传输会更快。 oss…...
Excel - VLOOKUP函数将指定列替换为字典值
背景:在根据各种复杂的口径导出报表数据时,因为关联的表较多、数据量较大,一行数据往往会存在三个以上的字典数据。 为了保证导出数据的效率,博主选择了导出字典code值后,在Excel中处理匹配字典值。在查询百度之后&am…...
实验室管理平台:Spring Boot技术构建
3系统分析 3.1可行性分析 通过对本实验室管理系统实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本实验室管理系统采用SSM框架,JAVA作为开发语言&a…...
操作系统进程和线程——针对实习面试
目录 操作系统进程和线程什么是进程和线程?进程和线程的区别?进程有哪些状态?什么是线程安全?如何实现线程安全?什么是线程安全?如何实现线程安全? 进程间的通信有哪几种方式?什么是…...
使用 cnpm 安装 Electron,才是正确快速的方法
当然,下面是总结的几种安装 Electron 的方法,包括使用 npm 和 cnpm,以及一些常见的问题解决技巧。 ### 1. 使用 npm 安装 Electron #### 步骤 1: 初始化项目 在你的项目目录中初始化一个新的 Node.js 项目: bash npm init -y …...
【人工智能】PyTorch、TensorFlow 和 Keras 全面解析与对比:深度学习框架的终极指南
文章目录 PyTorch 全面解析2.1 PyTorch 的发展历程2.2 PyTorch 的核心特点2.3 PyTorch 的应用场景 TensorFlow 全面解析3.1 TensorFlow 的发展历程3.2 TensorFlow 的核心特点3.3 TensorFlow 的应用场景 Keras 全面解析4.1 Keras 的发展历程4.2 Keras 的核心特点4.3 Keras 的应用…...
【第八课】Rust中的函数与方法
目录 前言 函数指针 函数当作另一个函数的参数 函数当作另一个函数的返回值 闭包 方法 关联函数 总结 前言 在前面几课中,我们都或多或少的接触到了rust中的函数,rust中的函数和其他语言的并没有什么不同,简单的语法不在这篇文章中赘…...
c语言学习25二维数组
1 二维数组 1.1二维数组认识 二维数组本质是一个数组。 举例: int a[10][3] 数组名 a; 元素个数10; 数组元素类型:int [3]; 数组元素下标:0~9 这是一个数组,有十个元素,每个元…...
如何理解Lua 使用虚拟堆栈
虚拟堆栈的基本概念 Lua使用虚拟堆栈来实现Lua和C(或其他宿主语言)之间的交互。这个虚拟堆栈是一个数据结构,用于存储Lua的值,如数字、字符串、表、函数等。它在Lua状态机(lua_State)内部维护,为…...
【倍数问题——同余系】
题目 代码 #include <bits/stdc.h> using namespace std; const int N 1e5 10, M 1e3 10; int maxx[M][4]; void consider(int r, int x) {if(x > maxx[r][1]){maxx[r][3] maxx[r][2];maxx[r][2] maxx[r][1];maxx[r][1] x;}else if(x > maxx[r][2]){maxx[…...
「San」监听DOM变化的方法
在 San框架 中监听组件内部字体大小并调整宽度,可以结合 自定义事件 或 数据绑定 来实现动态调整。San 框架没有直接的监听 DOM 尺寸变化的内置方法,但可以通过以下步骤实现: 方法一:使用 ResizeObserver 监听字体变化 在组件的 …...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
