当前位置: 首页 > news >正文

Vue3中搜索表单的二次封装

最近使用Vue3+ElementPlus开发项目,从整体上构思组件的封装。能写成组件的内容都进行封装,方便多个地方使用。
受AntDesign的启发,在项目中有搜索表单+table+分页的地方可以封装为一个组件,只需要对组件传入table的列,组成一个配置项,通过配置可以显示搜索表单、table项的内容展示等等。
那么在使用ElemenPlus开发时,是没有这样的组件可以使用的。又一想项目中好多个地方都有搜索表单+Table的形式,那不如直接封装个搜索表单,这样就省去了一遍一遍的表单的重复编写。封装好的组件只需要传入进入配置内容即可实现搜索的效果。

实现思路:

  1. 搜索表单无非就是文本框、选择框、时间选择、时间范围选择、数字框,通过配置项里传入type即可判断展示哪种类型的form-item。
  2. 数值绑定,v-model与传入项的匹配,在配置项中传入prop,然后在子组件中创建form响应式对象。
  3. 数据初始值、选项列表等等都通过配置项传入。
  4. 搜索表单的搜索与重置按钮,提交emit事件即可。

首先:创建SearchForm.vue组件

该组件实现了输入框、选择框、单日期、双日期(一般搜索表单也就这些,如果还有其他的类型,读者可以自己添加)。

<script setup>import { reactive, onMounted } from "vue"import DateRangePicker from '@/components/DateRangePicker/index.vue'const props = defineProps({itemList: Array})const emit = defineEmits(['search', 'reset'])let form = reactive({})onMounted(() => {props.itemList.map(item => {if(item.type === 'dateRange') {form[item.start] = ''form[item.end] = ''}else {form[item.prop] = item.initValue ? item.initValue : ''}})})
</script><template><el-form :model="form" inline label-width="120px"><template v-for="(item, index) in props.itemList" :key="index"><el-form-item:label="item.label":prop="item.prop"><el-select v-if="item.type === 'select'" v-model="form[item.prop]" placeholder="请选择" clearable><el-option v-for="i in item.list" :key="i.value" :label="i.label" :value="i.value"/></el-select><el-date-picker v-if="item.type === 'date'" :type="item.dateType" v-model="form[item.prop]" placeholder="请选择" clearable/><date-range-pickerv-if="item.type === 'dateRange'"v-model:start="form[item.start]"v-model:end="form[item.end]"/><el-input-number v-if="item.type === 'number'" v-model="form[item.prop]" placeholder="请输入" clearable/><el-input v-if="item.type === 'input'" v-model="form[item.prop]" placeholder="请输入" clearable/></el-form-item></template><el-form-item><el-button @click="emit('search', form)" type="primary" icon="Search">查询</el-button><el-button @click="emit('reset')" type="primary" plain icon="Refresh">重置</el-button></el-form-item></el-form>
</template>

其次:DateRangePicker组件

这个组件是用来实现选择范围日期的,因为范围日期返回的是一个数组,如果不进行封装处理一下的话,在项目中每写一个该组件都会要写change事件来处理数据值,还挺麻烦。封装之后,只需要将对应的model传给该组件即可实现双向绑定。

<script setup>
import { ref } from "vue";
const emit = defineEmits(['update:start', 'update:end'])
const props = defineProps({start: {type: String,required: true},end: {type: String,required: true},type: {default: 'daterange'  // daterange、datetimerange、monthrange},format: {default: 'YYYY-MM-DD'},valueFormat: {default: 'YYYY-MM-DD HH:mm:ss'}
})
let dateRange = ref([])const dateChange = (e) => {emit('update:start', e ? e[0] : '')emit('update:end', e ? e[1] : '')
}
</script><template><el-date-picker v-model="dateRange":type="props.type":format="props.format":value-format="props.valueFormat"start-placeholder="开始日期"end-placeholder="结束日期"@change="dateChange"/>
</template>

最后一步:使用SearchForm组件

经过前两步的封装之后,在使用的SearchForm组件时,简直是爽的不要不要的。看示例:

<script setup>import { reactive, ref } from 'vue'import SearchForm from '@/components/SearchForm/index.vue'import ProListItem from '@/views/project/components/ProListItem.vue'import { projectList } from '@/api/project';const searchFormList = [{label: '项目名称', prop: 'name', type: 'input'},{label: '项目编码', prop: 'code', type: 'input'},{label: '项目描述', prop: 'desc', type: 'select', list: [{label: '未开始', value: 1}, {label: '已开始', value: 2}]},{label: '创建日期', type: 'dateRange', start: 'startTime', end: 'endTime'}]const dataSource = ref([])const queryForm = ref()const pagination = reactive({pageNum: 1,pageSize: 10,total: 0})const search = (form) => {console.log(form);queryForm.value = formqueryProject()}const queryProject = () => {projectList({...queryForm.value,pageNum: pagination.pageNum,pageSize: pagination.pageSize}).then((result) => {dataSource.value = result.data.listdata.total = result.data.total}).catch((err) => {});}
</script>
<template><search-form :item-list="searchFormList"@search="search"/><pro-list-item :data="dataSource"/>
</template>

啥也不说了,直接看示例,用起来多方便!!!只要项目中有要写搜索表单的地方,直接引入SearchForm组件,配置一下itemList即可实现完整功能!学会了的小伙伴赶紧去用起来吧。

http://www.lryc.cn/news/137111.html

相关文章:

  • 百度23Q2财报最新发布:营收利润加速增长,AI+生态战略渐显规模
  • 一个pdf文件分割成两个
  • Android 保存图片
  • Android相机-架构
  • 从C语言到C++_33(C++11_上)initializer_list+右值引用+完美转发+移动构造/赋值
  • 如何在Linux系统中处理PDF文件?
  • SpringBoot实现热部署/加载
  • 我是如何使用Spring Retry减少1000 行代码
  • ARM开发(stm32 cortex-A7核IIC实验)
  • 「Java」《Java集合框架详解:掌握常用集合类,提升开发效率》
  • 游戏出海需知:Admob游戏广告变现策略
  • 【linux】NFS调试总结
  • wireshark进行网络监听
  • 时间复杂度
  • Unity实现广告滚动播放、循环播放、鼠标切换的效果
  • LangChain + Streamlit + Llama:将对话式AI引入本地机器
  • Python 读写 Excel 文件库推荐和使用教程
  • “深入解析JVM:理解Java虚拟机的工作原理和优化技巧“
  • 解决SEGGER Embedded Studio无法显示Nordic MCU外设寄存器问题
  • Oracle-day1:scott用户、查询、取整、截取、模糊查询、别名——23/8/23
  • stm32之3.key开关
  • GPT带我学-设计模式-代理模式
  • VMware Workstation Pro 无法使用开机状态下拍的快照来克隆虚拟机,怎么解决?
  • 【JAVA】XML及其解析技术、XML检索技术、设计模式
  • Ansible 自动化安装软件
  • 简单介绍 React Native 整合 Formik 实现表单校验
  • 蓝帽杯半决赛2022
  • 电路学习+硬件每日学习十个知识点(40)23.8.20 (希腊字母读音,阶跃信号和冲激信号的关系式,信号的波形变换,信号的基本运算,卷积积分,卷积和)
  • Python——列表(list)推导式
  • 代码随想录算法训练营day43 | LeetCode 1049. 最后一块石头的重量 II 494. 目标和 474. 一和零