前端查询表单的封装

本文介绍了一个基于Vue3、TypeScript和AntD库构建的可扩展查询表单组件,包括文本框、下拉选择和时间选择功能。组件支持验证、数据提交和重置操作,允许用户自定义其他表单元素。在父组件中通过属性设置规则和数据,实现灵活的搜索功能。
摘要由CSDN通过智能技术生成

我这里只是简单封装了一个查询表单组件,目前就是只写了文本框,下拉选和时间控件,如果需要别的表单,可以在自行扩展,这里是使用的antD+vue3+ts

  1. js部分
<script setup lang='ts'>
import { ref, reactive, useAttrs, useSlots, getCurrentInstance, onMounted, computed } from 'vue'
import { Input, Button, CheckboxGroup, Tree, Table, Badge, message, Pagination, Select, SelectOption, Form, FormItem, DatePicker } from 'ant-design-vue';
import { SearchOutlined } from '@ant-design/icons-vue';
import type { FormInstance } from 'ant-design-vue/es/form/Form';
const props = defineProps({
  modelValue: {
    type: Object,
    required: true,
  },
  rules: {
    type: Object,
    required: false,
  },
  searchFormArr: {
    type: Array,
    required: true,
  },
})
const formRef = ref<FormInstance>();
const emit = defineEmits(['update:modelValue', 'reset', 'onSearch'])
const submitSearch = () => {
  formRef.value.validate().then(() => {
    console.log('提交的数据为', formState)
    emit('onSearch')
  }).catch((e) => {
    console.log(e)
  })

}
const reset = () => {
  formRef.value.clearValidate();
  submitSearch();
  emit('reset')
}
const formState = computed({
  get() {
    return new Proxy(props.modelValue, {
      set(obj, name, val) {
        console.log('emit', obj, name, val, props.modelValue)
        emit('update:modelValue', {
          ...obj,
          [name]: val
        })
        return true;
      }
    })
    // return props.modelValue
  },
  set(val) {
    emit('update:modelValue', val)
  }
})
</script>

2.dom结构部分

<template>
  <Form ref="formRef" name="formSearch" autocomplete="off" :model="formState" @finish="submitSearch" class="my-form"
    :rules="rules" layout="inline" style="width:100%;position:relative;" v-bind="{
      labelCol: { span: 5, wrapper: 6 }
    }">

    <FormItem :label="item.title" v-for="(item, index) in searchFormArr" :key="index" :name="item.key"
      :style="{ width: `${item.width}%`, marginBottom: '20px' }">
      <template v-if="item.type == 'input'">
        <Input v-model:value="formState[item.key]" :placeholder="item.placeholder" />
      </template>
      <!-- 下拉选 -->
      <template v-if="item.type == 'select'">
        <!-- 多选 -->
        <template v-if="item.mode == 'multiple'">
          <Select :placeholder="item.placeholder" mode="tags" v-model:value="formState[item.key]" @select="submitSearch">
            <template v-for="i in item.options" :key="i.value">
              <SelectOption :value="i.value">{{
                i.label
              }}</SelectOption>
            </template>
          </Select>
        </template>
        <!-- 单选 -->
        <template v-else>
          <Select :placeholder="item.placeholder" v-model:value="formState[item.key]" @select="submitSearch">
            <template v-for="i in item.options" :key="i.value">
              <SelectOption :value="i.value">{{
                i.label
              }}</SelectOption>
            </template>
          </Select>
        </template>
      </template>
      <template v-if="item.type == 'date'">
        <DatePicker :show-time="item.showTime" :placeholder="item.placeholder" v-model:value="formState[item.key]"
          format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" @change="item.change"
          :disabled-date="item.disabledDate" />
      </template>
    </FormItem>
    <FormItem style="text-align:right;position:absolute;right:0;bottom:20px;margin-right:0;width:150px;">
      <Button type="primary" html-type="submit">搜索</Button>
      <Button type="primary" @click="reset" style="margin-left:5px;">重置</Button>
    </FormItem>
  </Form>
</template>

在父组件中的使用

<MySearch v-model="searchForm" :searchFormArr="searchFormArr" :rules="rules" @onSearch="onSearch"  @reset="resetForm" />
		const disabledDate = (current: any) => {
            if (current > dayjs().subtract(180, 'day') && (current <= dayjs())) {
                return false;
            } else {
                return true;
            }
        }
        const rules: Record<string, Rule[]> = {
            dateValue: [{ required: true, message: '请选择时间', trigger: 'blur' }],
        };
        const searchForm = ref({
            dateValue: '',
            deviceType: [],
            equipmentInput: '',
        })
        const searchFormArr = ref([
            {
                key: 'dateValue',
                title: '选择时间',
                type: 'date',
                showTime: true,
                placeholder: '选择时间',
                width: 100,
                disabledDate: disabledDate,
            },
            {
                key: 'deviceType',
                title: '',
                type: 'select',
                mode: 'multiple',
                placeholder: '设备类型',
                options: [],
                width: 25,
            },
            {
                key: 'equipmentInput',
                title: '',
                type: 'input',
                placeholder: '请输入',
                width: 40
            },
        ])
        // 重置
        const resetForm = () => {
            searchForm.value.dateValue = ''
            searchForm.value.deviceType = []
            searchForm.value.equipmentInput = ''
        };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值