vue3+arco design通过动态表单方式实现自定义筛选

目录

1.说明

2.示例

3.运行截图

​编辑 4.总结


1.说明

        (1) 本文主要实现通过动态表单的方式实现自定义筛选的功能,用户可以自己添加筛选的项目,筛选条件及筛选内容。

        (2) 每个项目的筛选包含筛选项目,筛选条件,筛选方式及筛选值。

                筛选项目代表表中的字段,如姓名,年龄等

                筛选条件包含等于,不等于,大于,小于,包含等

                筛选类型包含手动输入值的方式,通过下拉进行选择的方式,和表中的其他字段进行比较的方式

                筛选值可以手动输入,可以通过下拉进行选择,也可以选择某个日期。

2.示例

<template><a-modal :visible="visibleFlag" @ok="handleOk" @cancel="handleCancel" unmountOnClose width="auto"><div style="text-align: right"><a-button @click="handleAdd()">Add</a-button></div><a-form :model="form" layout='vertical' style="width: 1000px;height: 400px;" ref="formRef"><div v-for="(item,index) in form.data"><a-row :gutter="10"><a-col :span="5"><a-form-item :field="`data[${index}].filterColumn`" label="Column" :hide-label="index != 0":rules="[{required:true,message:'Column不能为空'}]"validate-trigger="blur"><a-select v-model="item.filterColumn" :style="{width:'500px'}" placeholder="Please select ..."@blur="columnBlur(form.data[index].filterColumn, form.data[index].filterType , index)" allow-clear><a-option v-for="item of columns" :value="item.value" :label="item.label"/></a-select></a-form-item></a-col><a-col :span="6"><a-form-item :field="`data[${index}].filterOperation`" label="Operation" :hide-label="index != 0":rules="[{required:true,message:'Operation不能为空'}]"validate-trigger="blur"><a-select v-model="item.filterOperation" :style="{width:'500px'}"placeholder="Please select ..." allow-clear><a-option v-for="item of filterOpeData[index]" :value="item.value" :label="item.label"/></a-select></a-form-item></a-col><a-col :span="5"><a-form-item :field="`data[${index}].filterType`" label="Type" :hide-label="index != 0":rules="[{required:true,message:'Type不能为空'}]"validate-trigger="blur"><a-select v-model="item.filterType" :style="{width:'500px'}" placeholder="Please select ..."@blur="typeBlur(form.data[index].filterColumn, form.data[index].filterType, index)" allow-clear><a-option v-for="item of filterTypeData" :value="item.value" :label="item.label"/></a-select></a-form-item></a-col><a-col :span="5"><a-form-item :field="`data[${index}].filterValue`" label="Value" :hide-label="index != 0":rules="[{required:true,message:'Value不能为空'}]"validate-trigger="blur"><a-input v-model="item.filterValue" :style="{width:'500px'}"placeholder="Please enter something"allow-clear v-if="valueFlag[index] == 0"/><a-select v-model="item.filterValue" :style="{width:'400px'}" placeholder="Please select ..."v-if="valueFlag[index] == 1" allow-clear><a-option v-for="item of colValList[index]" :value="item.value" :label="item.label"/></a-select><a-date-picker v-model="item.filterValue" :style="{width:'400px'}"v-if="valueFlag[index] == 2" /></a-form-item></a-col><a-col :span="3"><a-button v-show="index != 0" @click="handleDelete(index)" :style="{marginLeft:'10px'}">Delete</a-button></a-col></a-row></div></a-form></a-modal>
</template><script lang="ts" setup>
import {onMounted, ref} from 'vue';
import {Message} from '@arco-design/web-vue';
import {FormInstance} from '@arco-design/web-vue/es/form';const formRef = ref<FormInstance>();
const visibleFlag = ref(false)// 0:输入框;1:下拉选择器;2:日期
const valueFlag = ref([] as any)
valueFlag.value.push(0)const form = ref({data: [{filterColumn: '',filterOperation: '',filterType: '',filterValue: ''}]
})const colValList = ref([] as any)const filterOpeData = ref([] as any)const filterTypeData = [{value: '0',label: 'Value',
}, {value: '1',label: 'Column',
}, {value: '2',label: 'User List',
}]const operationData1 = [{value: '1', label: 'EQUAL'},{value: '2', label: 'GREATER_THAN'},{value: '3', label: 'GREATER_THAN_OR_EQUAL'},{value: '4', label: 'LESS_THAN'},{value: '5', label: 'LESS_THAN_OR_EQUAL'},{value: '6', label: 'NOT_EQUAL'}]
const operationData2 = [{value: '1', label: 'EQUAL'},{value: '2', label: 'GREATER_THAN'},{value: '3', label: 'GREATER_THAN_OR_EQUAL'},{value: '4', label: 'LESS_THAN'},{value: '5', label: 'LESS_THAN_OR_EQUAL'},{value: '6', label: 'NOT_EQUAL'},{value: '9', label: 'CONTAINS'},{value: '10', label: 'STARTS_WITH'},{value: '11', label: 'ENDS_WITH'},{value: '12', label: 'DOES_NOT_START_WITH'},{value: '13', label: 'DOES_NOT_END_WITH'},{value: '14', label: 'DOES_NOT_CONTAIN'},{value: '15', label: 'STARTS_OR_ENDS_WITH'}
]const handleOk = async () => {const validRes = await formRef.value?.validate();if (!validRes) {visibleFlag.value = false;console.log(JSON.stringify(form.value.data))} else {console.log("校验失败")}
}const handleCancel = () => {visibleFlag.value = false;
}const handleDelete = (index: any) => {form.value.data.splice(index, 1);valueFlag.value.splice(index, 1);colValList.value.splice(index, 1);}const handleAdd = () => {form.value.data.push({filterColumn: '',filterOperation: '',filterType: '',filterValue: ''})valueFlag.value.push(0)
}const columnBlur = (colVal: any, typeVal: any, index: any) => {if (!colVal) {return}const col = columns.value.find((item: { value: any; }) => item.value == colVal)if (col.type == 'text' || col.type == 'number') {filterOpeData.value[index] = operationData2} else {filterOpeData.value[index] = operationData1}if (col.type == 'list' && typeVal != '1') {valueFlag.value[index] = 1colValList.value[index] = [{value: '1',label: '处理提交'}, {value: '2',label: '处理中'}, {value: '3',label: '处理完成'}]}if (col.type == 'date') {valueFlag.value[index] = 2}
}const typeBlur = (colVal: any, typeVal: any, index: any) => {if (typeVal == '1') {if (!colVal) {Message.error({content: 'column信息不能为空', position: 'top'});return} else {const col = columns.value.find((item: { value: any; }) => item.value == colVal)if (col.type == 'list') {Message.error({content: 'list类型的column不支持和其他列进行比较', position: 'top'});form.value.data[index].filterType = ''return}valueFlag.value[index] = 1if (col.type == 'date') {colValList.value[index] = columns.value.filter((item: { type: string; }) => item.type == 'date')} else if (col.type == 'text') {colValList.value[index] = columns.value.filter((item: { type: string; }) => item.type == 'text' || item.type == 'number')} else if (col.type == 'number') {colValList.value[index] = columns.value.filter((item: { type: string; }) => item.type == 'number')} else if (col.type == 'list') {} else {colValList.value[index] = []}}}}// 打开弹窗
const openDialog = () => {visibleFlag.value = true;
};
// 导出方法在父组件中进行使用
defineExpose({openDialog});const columns = ref()
const getColumnList = () => {columns.value = [{value: '12',label: 'genoId',type: 'text'},{value: '13',label: 'status',type: 'list'},{value: '14',label: 'createTime',type: 'date'},{value: '15',label: 'qty',type: 'number'}]
}// 组件完成初始渲染并创建 DOM 节点后运行
onMounted(async () => {await getColumnList()
})</script><script lang="ts">
export default {name: "dynamicFilter"
}
</script><style scoped></style>

 说明:

        ①通过表单的方式进行实现,表单关联的数据源form是对象格式,如下:

const form = ref({data: [{filterColumn: '',filterOperation: '',filterType: '',filterValue: ''}]
})

       对象内是一个id为data的数组,数组内的每条数组则存储一个项目的筛选内容,包含筛选项目,筛选条件,筛选方式及筛选值。数据源设置为对象是为了进行校验处理,如果是数组格式,无法实现动态表单的的校验(不同的前端框架,可能会有所不同,但推荐使用对象格式)

        ②动态表单的实现
        在form标签内嵌套div标签,并在div标签上进行循环form.data,如果动态的项目只有一个,可以直接在form-item上进行循环处理。具体的每个表单项可以通过form.data[index].表单项名的方式进行绑定,也可以通过item.表单项名的方式进行绑定。点击新增按钮,会向form.data中push一条新数据,添加的筛选项目后面有删除按钮,点击删除按钮,通过form.data.splice方法删除数组中的元素。

        ③动态表单的校验处理

        在每个表单项中添加校验规则,不要在form上添加校验规则

        在arco design框架中的动态表单校验如下:

            <a-form-item :field="`data[${index}].filterColumn`" label="Column" :hide-label="index != 0":rules="[{required:true,message:'Column不能为空'}]"validate-trigger="blur"><a-select v-model="item.filterColumn" :style="{width:'500px'}" placeholder="Please select ..."@blur="columnBlur(form.data[index].filterColumn, form.data[index].filterType , index)" allow-clear><a-option v-for="item of columns" :value="item.value" :label="item.label"/></a-select></a-form-item>

 通过rules关联校验规则,注意field属性的设置,在arco design中field需要进行如上设置,结果例如:data[0].filterColumn。

在arco design中是设置field属性,在element ui中是设置prop属性,并且内容的设置方式也不一样,需要注意。

        ④提交时的校验

        当前表单嵌套在对话框中,点击确定按钮时,需要先进行表单的校验处理,如下:

const handleOk = async () => {const validRes = await formRef.value?.validate();if (!validRes) {visibleFlag.value = false;console.log(JSON.stringify(form.value.data))} else {console.log("校验失败")}
}

通过调用表单的ref对象的validate方法,如果校验失败则返回失败的项目的field属性内容及错误信息,如果成功则返回undefined,所以通过判断返回结果就可以判断校验成功与否。 

校验失败的返回信息如下

{"data[0].filterColumn": {"label": "Column","field": "data[0].filterColumn","type": "string","isRequiredError": true,"message": "Column不能为空"},"data[0].filterOperation": {"label": "Operation","field": "data[0].filterOperation","type": "string","isRequiredError": true,"message": "Operation不能为空"},"data[0].filterType": {"label": "Type","field": "data[0].filterType","type": "string","isRequiredError": true,"message": "Type不能为空"},"data[0].filterValue": {"label": "Value","field": "data[0].filterValue","type": "string","isRequiredError": true,"message": "Value不能为空"},"data[1].filterColumn": {"label": "Column","field": "data[1].filterColumn","type": "string","isRequiredError": true,"message": "Column不能为空"},"data[1].filterOperation": {"label": "Operation","field": "data[1].filterOperation","type": "string","isRequiredError": true,"message": "Operation不能为空"},"data[1].filterType": {"label": "Type","field": "data[1].filterType","type": "string","isRequiredError": true,"message": "Type不能为空"},"data[1].filterValue": {"label": "Value","field": "data[1].filterValue","type": "string","isRequiredError": true,"message": "Value不能为空"},"data[2].filterColumn": {"label": "Column","field": "data[2].filterColumn","type": "string","isRequiredError": true,"message": "Column不能为空"},"data[2].filterOperation": {"label": "Operation","field": "data[2].filterOperation","type": "string","isRequiredError": true,"message": "Operation不能为空"},"data[2].filterType": {"label": "Type","field": "data[2].filterType","type": "string","isRequiredError": true,"message": "Type不能为空"},"data[2].filterValue": {"label": "Value","field": "data[2].filterValue","type": "string","isRequiredError": true,"message": "Value不能为空"}
}

校验通过后输出的form.data信息,如下:

[{"filterColumn": "12","filterOperation": "1","filterType": "0","filterValue": "23"
}, {"filterColumn": "13","filterOperation": "1","filterType": "0","filterValue": "1"
}, {"filterColumn": "14","filterOperation": "2","filterType": "0","filterValue": "2024-05-14"
}]

3.运行截图

校验失败

输入内容后,校验通过

 4.总结

①注意表单绑定的数据源的格式及不同前端框架的校验的方式

②为了使画面更加友好,可以将表单放在表格中

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3018284.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

重学java 30.API 1.String字符串

于是&#xff0c;虚度的光阴换来了模糊 —— 24.5.8 一、String基础知识以及创建 1.String介绍 1.概述 String类代表字符串 2.特点 a.Java程序中的所有字符串字面值(如“abc”)都作为此类的实例(对象)实现 凡是带双引号的&#xff0c;都是String的对象 String s "abc&q…

在家中访问一个网站的思考

在家中访问一个网站的思考 1、家庭网络简介2、家庭WLAN DHCP2.1、家庭路由器PPPOE拨号2.2、DHCP&#xff08;动态主机配置协议&#xff09;2.3、接入家庭网的主机IP地址2.4、家庭总线型以太网2.5、Mac地址2.6、ARP协议2.7、IP协议 & UDP/TCP协议2.8、NAT&#xff08;Netwo…

【一起深度学习吧!!!!!】24/05/03

卷积层里的多输入输出通道 1、 多输入通道&#xff1a;代码演示&#xff1a; 多输出通道&#xff1a;代码实现&#xff1a; 1、 多输入通道&#xff1a; 当输入包含多个通道时&#xff0c;需要构造一个输入通道与之相等的卷积核&#xff0c;以便进行数据互相关计算。 例如李沐…

Ubuntu24.04安装中文输入法

Ubuntu24.04安装中文输入法 为了更好的体验&#xff0c;请访问个人博客 www.huerpu.cc:7000 一、添加中文语言支持 在安装中文输入法之前&#xff0c;首选要添加中文语言支持。选择System&#xff0c;点击Region & Language。 点击Manage Install Languages。 点击Insta…

repo跟git的关系

关于repo 大都讲的太复杂了,大多是从定义角度跟命令角度去讲解,其实从现实项目使用角度而言repo很好理解. 我们都知道git是用来管理项目的,多人开发过程中git功能很好用.现在我们知道一个项目会用一个git仓库去管理,项目的开发过程中会使用git创建分支之类的来更好的维护项目代…

css 文字描边

又是抄样式的一天。这次是百度地图。实现了问题和图形描边的效果。 代码&#xff1a; .BMap_scaleTxt.dark {color: #fff;text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000; } 效果&#xff1a;

安装numpy遇到的问题

安装numpy的时候提示无法安装如下&#xff1a; (venv) E:\works\AI\venv\Scripts>pip install numpy pandas matplotlib jupyter -i https://pypi.douban.com/simple Looking in indexes: https://pypi.douban.com/simple WARNING: Retrying (Retry(total4, connectNone, r…

分析师常用商业分析模型

一、背景 在用户调研中&#xff0c;我们发现分析师对商业分析模型的使用还是比较频繁。本文主要对用户调研结果中的分析师常用商业分析模型以及一些业界经典的商业分析模型进行分析&#xff0c;并梳理出执行落地流程&#xff0c;以此来指导分析师工具设计分析功能的引导性。 …

软件测试--接口测试

接口测试&#xff1a;直接对后端服务的测试&#xff0c;是服务端性能测试的基础 接口&#xff1a;系统之间数据交互的通道 接口测试&#xff1a;校验接口响应数据与预期数据是否一致

【JavaEE初阶系列】——Servlet运行原理以及Servlet API详解

目录 &#x1f6a9;Servlet运行原理 &#x1f6a9;Servlet API 详解 &#x1f393;HttpServlet核心方法 &#x1f393;HttpServletRequest核心方法 &#x1f388;核心方法的使用 &#x1f534;获取请求中的参数 &#x1f4bb;query string &#x1f4bb;直接通过form表…

回归分析的理解

1.是什么&#xff1a; 2.回归问题的求解&#xff1a; 首先是根据之前的数据确定变量和因变量的关系根据关系去预测目标数据根据结果做出判断 2.1如何找到关系&#xff1f; y’是根据模型生成的预测结果&#xff1a; y’axb&#xff0c;而我们的目的是y’和y(正确的结果)之间…

构造照亮世界——快速沃尔什变换 (FWT)

博客园 我的博客 快速沃尔什变换解决的卷积问题 快速沃尔什变换&#xff08;FWT&#xff09;是解决这样一类卷积问题&#xff1a; ci∑ij⊙kajbkc_i\sum_{ij\odot k}a_jb_k ci​ij⊙k∑​aj​bk​其中&#xff0c;⊙\odot⊙ 是位运算的一种。举个例子&#xff0c;给定数列 a,…

二叉搜索树相关

二叉搜索树 定义&#xff1a;对二叉搜索树的一些操作基本结构Insert操作Find操作Erase操作 InOrder遍历二叉树操作模拟字典模拟统计次数 定义&#xff1a; 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树:若它的左子树不为空&a…

品鉴中的艺术表达:如何将红酒与绘画、雕塑等艺术形式相结合

品鉴雷盛红酒不仅是一种味觉的享受&#xff0c;更是一种艺术的体验。将雷盛红酒与绘画、雕塑等艺术形式相结合&#xff0c;能够创造出与众不同的审美体验&#xff0c;进一步丰富品鉴的内涵。 首先&#xff0c;绘画作为视觉艺术的一种表现形式&#xff0c;能够通过色彩和构图来传…

Linux:进程等待 进程替换

Linux&#xff1a;进程等待 & 进程替换 进程等待wait接口statuswaitpid接口 进程替换exec系列接口 当一个进程死亡后&#xff0c;会变成僵尸进程&#xff0c;此时进程的PCB被保留&#xff0c;等待父进程将该PCB回收。那么父进程要如何回收这个僵尸进程的PCB呢&#xff1f;父…

47.Redis学习笔记

小林coding -> 图解redis的学习笔记 文章目录 Rediswindwos安装docker安装redis启动redis使用RDM访问虚拟机中的redispython连接redis缓存穿透、击穿、雪崩基本数据类型高级数据类型高并发指标布隆过滤器分布式锁Redis 的有序集合底层为什么要用跳表&#xff0c;而不用平衡…

什么是 AI Agent ?

&#xff08;注&#xff1a;本文为小报童精选文章。已订阅小报童或加入知识星球「玉树芝兰」用户请勿重复付费&#xff09; 讲解的同时&#xff0c;也给你推荐一些实用的学习资源。 AI agent &#xff08;智能体 / 代理&#xff09;这个词儿最近非常流行&#xff0c;似乎「大语…

目标检测实战(八): 使用YOLOv7完成对图像的目标检测任务(从数据准备到训练测试部署的完整流程)

文章目录 一、目标检测介绍二、YOLOv7介绍三、源码/论文获取四、环境搭建4.1 环境检测 五、数据集准备六、 模型训练七、模型验证八、模型测试九、错误总结9.1 错误1-numpy jas mp attribute int9.2 错误2-测试代码未能跑出检测框9.3 错误3- Command git tag returned non-zero…

RabbitMQ高级(MQ的问题,消息可靠性,死信交换机,惰性队列,MQ集群)【详解】

目录 一、MQ的问题 1. 问题说明 2. 准备代码环境 1 创建project 2 创建生产者模块 3 创建消费者模块 二、消息可靠性 1. 介绍 2. 生产者确认机制 3. MQ消息持久化 4. 消费者确认机制 5. 消费者auto模式的失败重试 6. 小结 三、死信交换机和延迟消息 1. 介绍 2. …

【EasySpider】EasySpider+mysql执行配置异常

问题 使用易采集工具操作时候&#xff0c;遇到一个执行异常&#xff0c;后来发现没有选择数据类型 Loading stealth.min.js MySQL config file path: ./mysql_config.json 成功连接到数据库。 Successfully connected to the database. Traceback (most recent call last):…