Skip to content

ContentFormHead 表头查询功能

提供表单等提供查询功能

何时使用

  • 表头查询既可以作为页头,作为页面的表格数据的查询功能,也可以作为某个表格数据的查询功能

开发者注意事项

  • 在不传入 cols 参数的情况下,ContentFormHead 会根据屏幕的宽度自动调节(一行可以放置几列)

更新内容

  • onReset 回调函数将返回一个 Promise 实例;
  • onSubmit 回调函数将返回一个 Promise 实例;
  • onExport回调函数将返回一个 Promise 实例;
  • 新增提交按钮、导出按钮、重置按钮用户反馈交互,防止用户持续提交动作;
  • 将原本内置的导出文件功能删除,新版本中开发者通过 exportTableList(query) 方法自定义导出文件;
  • 组件内部逻辑优化,组件性能有所提升;
  • 组件样式微调;
  • 添加了 ref 可获取组件的实例对象,该实例对象上绑定了如下属性:
    • form 是表单实例;
    • getCurrentFormData 用于获取格式化后的表单数据;

代码演示

案例一(指定表单查询默认值)

AAA
vue
<script setup lang="ts">
import { ref } from 'vue';
import { delay } from '@/utils';
import { ContentFormHeader } from '@/library';
import dayjs from 'dayjs';

const queryList = ref([
  {
    name: 'name',
    title: '查询名称',
    formType: 'input',
    watch: (name: string, formModels: any) => {
      // 每当查询名称表单字段的值发生变化时,重置 时间查询 表单项
      formModels.time = null;
    },
    initialValue: 'hello world',
  },
  {
    name: 'time',
    title: '时间查询',
    formType: 'datePicker',
    properties: {
      style: { width: '100%' },
    },
    dataFormat: (value: any) => {
      return { time: value.startOf().format('YYYY-MM-DD') };
    },
    initialValue: dayjs('2024-07-01'),
  },
  {
    name: 'type',
    title: '类型查询',
    formType: 'select',
    options: [
      { value: '1', label: 'AAA' },
      { value: '2', label: 'BBB' },
      { value: '3', label: 'CCC' },
    ],
    initialValue: '1',
  },
  {
    name: 'timeRange',
    title: '时间范围',
    formType: 'rangePicker',
    properties: {
      style: { width: '100%' },
    },
    dataFormat: (value: any) => {
      return {
        startTime: value[0].startOf().format('YYYY-MM-DD'),
        endTime: value[1].endOf().format('YYYY-MM-DD'),
      };
    },
    initialValue: [dayjs().startOf('week'), dayjs().endOf('week')],
  },
]);

async function handleSubmit(values: any) {
  console.log(values);
  return delay(1000, null);
}

async function handleReset(values: any) {
  console.log(values);
  return delay(1000, null);
}

async function handleExport(values: any) {
  console.log(values);
  return delay(1000, null);
}
</script>

<template>
  <ContentFormHeader
    :queryList="queryList"
    :defaultExpand="false"
    :submit="handleSubmit"
    :reset="handleReset"
    :export="handleExport"
  />
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { delay } from '@/utils';
import { ContentFormHeader } from '@/library';
import dayjs from 'dayjs';

const queryList = ref([
  {
    name: 'name',
    title: '查询名称',
    formType: 'input',
    watch: (name: string, formModels: any) => {
      // 每当查询名称表单字段的值发生变化时,重置 时间查询 表单项
      formModels.time = null;
    },
    initialValue: 'hello world',
  },
  {
    name: 'time',
    title: '时间查询',
    formType: 'datePicker',
    properties: {
      style: { width: '100%' },
    },
    dataFormat: (value: any) => {
      return { time: value.startOf().format('YYYY-MM-DD') };
    },
    initialValue: dayjs('2024-07-01'),
  },
  {
    name: 'type',
    title: '类型查询',
    formType: 'select',
    options: [
      { value: '1', label: 'AAA' },
      { value: '2', label: 'BBB' },
      { value: '3', label: 'CCC' },
    ],
    initialValue: '1',
  },
  {
    name: 'timeRange',
    title: '时间范围',
    formType: 'rangePicker',
    properties: {
      style: { width: '100%' },
    },
    dataFormat: (value: any) => {
      return {
        startTime: value[0].startOf().format('YYYY-MM-DD'),
        endTime: value[1].endOf().format('YYYY-MM-DD'),
      };
    },
    initialValue: [dayjs().startOf('week'), dayjs().endOf('week')],
  },
]);

async function handleSubmit(values: any) {
  console.log(values);
  return delay(1000, null);
}

async function handleReset(values: any) {
  console.log(values);
  return delay(1000, null);
}

async function handleExport(values: any) {
  console.log(values);
  return delay(1000, null);
}
</script>

<template>
  <ContentFormHeader
    :queryList="queryList"
    :defaultExpand="false"
    :submit="handleSubmit"
    :reset="handleReset"
    :export="handleExport"
  />
</template>

案例二(指定列数)

请输入类型查询
vue
<script setup lang="ts">
import { ref } from 'vue';
import { delay } from '@/utils';
import { Button } from 'ant-design-vue';
import { ContentFormHeader } from '@/library';
import type { Cols } from '@/library/ContentFormHeader';

const headerRef = ref<InstanceType<typeof ContentFormHeader>>();
const cols = ref<Cols>(2);
const queryList = ref([
  {
    name: 'name',
    title: '查询名称',
    formType: 'input',
  },
  {
    name: 'time',
    title: '时间查询',
    formType: 'datePicker',
    properties: {
      style: { width: '100%' },
    },
    dataFormat(value: any) {
      return {
        time: value.startOf('day').format('YYYY-MM-DD'),
      };
    },
  },
  {
    name: 'type',
    title: '类型查询',
    formType: 'select',
    options: [
      { value: '1', label: 'AAA' },
      { value: '2', label: 'BBB' },
      { value: '3', label: 'CCC' },
    ],
  },
  {
    name: 'timeRange',
    title: '时间范围',
    formType: 'rangePicker',
    properties: {
      style: { width: '100%' },
    },
    dataFormat(values: any) {
      return {
        startTime: values[0].startOf('day').format('YYYY-MM-DD'),
        endTime: values[1].endOf('day').format('YYYY-MM-DD'),
      };
    },
  },
]);

async function handleSubmit(values: any) {
  console.log(values);
  return delay(1000, null);
}

async function handleReset(values: any) {
  console.log(values);
  return delay(1000, null);
}

async function handleExport(values: any) {
  console.log(values);
  return delay(1000, null);
}

function getCurrentFormData() {
  console.log(headerRef.value!.getCurrentFormData());
}
</script>

<template>
  <Button.Group>
    <Button :type="cols === 2 ? 'primary' : 'default'" @click="cols = 2">2</Button>
    <Button :type="cols === 3 ? 'primary' : 'default'" @click="cols = 3">3</Button>
  </Button.Group>
  <Button @click="getCurrentFormData">获取表单信息</Button>

  <div :style="{ overflow: 'auto', marginTop: '20px' }">
    <div :style="{ width: '1300px' }">
      <ContentFormHeader
        ref="headerRef"
        showExport
        :cols="cols"
        :queryList="queryList"
        :reset="handleReset"
        :export="handleExport"
        :submit="handleSubmit"
      />
    </div>
  </div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { delay } from '@/utils';
import { Button } from 'ant-design-vue';
import { ContentFormHeader } from '@/library';
import type { Cols } from '@/library/ContentFormHeader';

const headerRef = ref<InstanceType<typeof ContentFormHeader>>();
const cols = ref<Cols>(2);
const queryList = ref([
  {
    name: 'name',
    title: '查询名称',
    formType: 'input',
  },
  {
    name: 'time',
    title: '时间查询',
    formType: 'datePicker',
    properties: {
      style: { width: '100%' },
    },
    dataFormat(value: any) {
      return {
        time: value.startOf('day').format('YYYY-MM-DD'),
      };
    },
  },
  {
    name: 'type',
    title: '类型查询',
    formType: 'select',
    options: [
      { value: '1', label: 'AAA' },
      { value: '2', label: 'BBB' },
      { value: '3', label: 'CCC' },
    ],
  },
  {
    name: 'timeRange',
    title: '时间范围',
    formType: 'rangePicker',
    properties: {
      style: { width: '100%' },
    },
    dataFormat(values: any) {
      return {
        startTime: values[0].startOf('day').format('YYYY-MM-DD'),
        endTime: values[1].endOf('day').format('YYYY-MM-DD'),
      };
    },
  },
]);

async function handleSubmit(values: any) {
  console.log(values);
  return delay(1000, null);
}

async function handleReset(values: any) {
  console.log(values);
  return delay(1000, null);
}

async function handleExport(values: any) {
  console.log(values);
  return delay(1000, null);
}

function getCurrentFormData() {
  console.log(headerRef.value!.getCurrentFormData());
}
</script>

<template>
  <Button.Group>
    <Button :type="cols === 2 ? 'primary' : 'default'" @click="cols = 2">2</Button>
    <Button :type="cols === 3 ? 'primary' : 'default'" @click="cols = 3">3</Button>
  </Button.Group>
  <Button @click="getCurrentFormData">获取表单信息</Button>

  <div :style="{ overflow: 'auto', marginTop: '20px' }">
    <div :style="{ width: '1300px' }">
      <ContentFormHeader
        ref="headerRef"
        showExport
        :cols="cols"
        :queryList="queryList"
        :reset="handleReset"
        :export="handleExport"
        :submit="handleSubmit"
      />
    </div>
  </div>
</template>

案例三(自定义表单项内容)

vue
<script setup lang="ts">
import { h, ref, toRaw } from 'vue';
import { delay } from '@/utils';
import { Checkbox } from 'ant-design-vue';
import { ContentFormHeader } from '@/library';

const queryList = ref([
  {
    name: 'name',
    title: '查询名称',
    formType: 'input',
  },
  {
    name: 'time',
    title: '时间查询',
    formType: 'datePicker',
    properties: {
      style: { width: '100%' },
    },
  },
  {
    name: 'timeRange',
    title: '时间范围',
    formType: 'rangePicker',
    properties: {
      style: { width: '100%' },
    },
  },
  {
    name: 'type',
    title: '类型查询',
    // component: () => h(Checkbox.Group, { options: [{ label :'A', value: 1 }, { label: 'B', value: 2 }] })
    component() {
      return h(Checkbox.Group, null, () => [
        h(Checkbox, { value: '1' }, () => 'A'),
        h(Checkbox, { value: '2' }, () => 'B'),
      ]);
    },
    dataFormat(value: any) {
      return { type: toRaw(value) };
    },
  },
]);

async function handleSubmit(values: any) {
  console.log(values);
  return delay(1000, null);
}

async function handleReset(values: any) {
  console.log(values);
  return delay(1000, null);
}
</script>

<template>
  <ContentFormHeader :queryList="queryList" :submit="handleSubmit" :reset="handleReset" />
</template>
<script setup lang="ts">
import { h, ref, toRaw } from 'vue';
import { delay } from '@/utils';
import { Checkbox } from 'ant-design-vue';
import { ContentFormHeader } from '@/library';

const queryList = ref([
  {
    name: 'name',
    title: '查询名称',
    formType: 'input',
  },
  {
    name: 'time',
    title: '时间查询',
    formType: 'datePicker',
    properties: {
      style: { width: '100%' },
    },
  },
  {
    name: 'timeRange',
    title: '时间范围',
    formType: 'rangePicker',
    properties: {
      style: { width: '100%' },
    },
  },
  {
    name: 'type',
    title: '类型查询',
    // component: () => h(Checkbox.Group, { options: [{ label :'A', value: 1 }, { label: 'B', value: 2 }] })
    component() {
      return h(Checkbox.Group, null, () => [
        h(Checkbox, { value: '1' }, () => 'A'),
        h(Checkbox, { value: '2' }, () => 'B'),
      ]);
    },
    dataFormat(value: any) {
      return { type: toRaw(value) };
    },
  },
]);

async function handleSubmit(values: any) {
  console.log(values);
  return delay(1000, null);
}

async function handleReset(values: any) {
  console.log(values);
  return delay(1000, null);
}
</script>

<template>
  <ContentFormHeader :queryList="queryList" :submit="handleSubmit" :reset="handleReset" />
</template>

案例四(使用插槽)

vue
<script setup lang="ts">
import { ref } from 'vue';
import { delay } from '@/utils';
import { Button } from 'ant-design-vue';
import { ContentFormHeader } from '@/library';

const headerRef = ref<InstanceType<typeof ContentFormHeader>>();
const queryList = ref([
  {
    name: 'name',
    title: '查询名称',
    formType: 'input',
  },
]);

async function handleSubmit(values: any) {
  console.log(values);
  return delay(1000, null);
}

async function handleReset(values: any) {
  console.log(values);
  return delay(1000, null);
}

function handleClick() {
  console.log(headerRef.value!.getCurrentFormData());
}
</script>

<template>
  <ContentFormHeader ref="headerRef" :queryList="queryList" hideResetButton :submit="handleSubmit" :reset="handleReset">
    <template #insertNode>
      <Button style="margin-left: 8px" @click="handleClick">自定义按钮</Button>
    </template>
  </ContentFormHeader>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { delay } from '@/utils';
import { Button } from 'ant-design-vue';
import { ContentFormHeader } from '@/library';

const headerRef = ref<InstanceType<typeof ContentFormHeader>>();
const queryList = ref([
  {
    name: 'name',
    title: '查询名称',
    formType: 'input',
  },
]);

async function handleSubmit(values: any) {
  console.log(values);
  return delay(1000, null);
}

async function handleReset(values: any) {
  console.log(values);
  return delay(1000, null);
}

function handleClick() {
  console.log(headerRef.value!.getCurrentFormData());
}
</script>

<template>
  <ContentFormHeader ref="headerRef" :queryList="queryList" hideResetButton :submit="handleSubmit" :reset="handleReset">
    <template #insertNode>
      <Button style="margin-left: 8px" @click="handleClick">自定义按钮</Button>
    </template>
  </ContentFormHeader>
</template>

ContentFormHeader API

propNamedescriptiontypedefault value
cols要展示的列数number-
queryList查询表单项集合QueryList-
showExport是否展示导出按钮boolean-
defaultExpand是否默认展开所有查询你表单项booleantrue
submitButtonText查询表单项按钮的文本string提交
hideResetButton是否隐藏重置表单项按钮stringfalse
submit表单提交事件(values:any) => Promise<any>-
reset表单重置事件(values:any) => Promise<any>-
export表单导出事件(values:any) => Promise<any>-

QueryList

propNamedescriptiontype
title查询表单项的 lebelstring
name查询表单项的 namestring
properties传递给渲染组件的属性对象集合object
watch监听方法,每当对应的表单项值改变时,就会触发function (value, formModels) {}
dataFormat数据格式化方法,将原始的表单项数据转换成接口需要的格式function(value) {}
component自定义表单项内容function() {}
formType表单项内容组件的类型input,select,rangePicker,datePicker,cascader
initialValue表单项的初始值any
dataIndex表单项的 name 字段(当 name 属性存在时,以 name 属性为准)string
name表单项的 name 字段string
options传递给表单项内容组件,当 formType 为 'select' 或 'cascader' 时可以使用any[]
placeholder表单项的 placeholderstring

Released under the MIT License.