Skip to content

查询表单

侧边栏筛选表单通用配置实例

表单数据模型
vue
<template>
	<div class="search-form-demo">
		<SearchForm :model-value="vm" :config="config" @query="handleQuery" @reset="handleReset">
			<!-- 参照 @CustomFormFieldComponentProps -->
			<template #custom="{ field, model, modelValue, options, onExpandInput, onExpandField }">
				<fk-space direction="vertical">
					<fk-button type="primary" size="mini" @click="e => onExpandInput()">自定义展开Input</fk-button>
					<fk-button type="primary" size="mini" @click="e => onExpandField()">自定义展开Field</fk-button>
				</fk-space>
				<JsonViewer :data="field" />
				<JsonViewer :data="model" />
				<JsonViewer :data="modelValue" />
				<JsonViewer :data="options" />
			</template>
		</SearchForm>
	</div>
	<h5 style="margin-top: 20px">表单数据模型</h5>
	<JsonViewer :data="vm" />
</template>

<script setup lang="tsx">
import { onUnmounted, reactive } from 'vue';
import { SearchForm } from '@erp/biz';
import { config } from './form-config.tsx';

config.queryPool = 'ceshi-search-form-1';
config.labelLayout = 'expand';

const vm = reactive({
	key1: '',
	key4: [],
	key10: [],
	key11: [],
	key7: [],
	key3: [],
});

const handleQuery = (model, params) => {
	console.log('query >>', model, params);
};

const handleReset = model => {
	console.log('reset >>', model);
};

/**
 * 动态更新选项
 */
const intervalId = setInterval(() => {
	const field = config.fields.find(item => item.key === 'custom');
	const num = Math.floor(Math.random() * 10);
	field.options = [];
	for (let i = 0; i < num; i++) {
		field.options.push({
			label: `选项${i}`,
			value: i,
		});
	}
}, 3000);

onUnmounted(() => {
	clearInterval(intervalId);
});
</script>

<style scoped lang="less">
.search-form-demo {
	height: 500px;

	.search-form {
		border: 1px solid var(--color-border-1);
	}
}
</style>
tsx
import type { SearchFormI } from '@erp/biz';

export const config: SearchFormI = {
	gridProps: {
		cols: 3,
		colGap: 12,
		rowGap: 16,
	},
	fields: [
		{
			key: 'key1',
			type: 'text',
			tooltip: '商品名称',
		},
		{
			key: 'key2',
			label: '商品编码',
			type: 'text',
		},
		{
			key: 'key3',
			label: '商品分类',
			type: 'select',
			multiple: true,
			options: [
				{
					value: '1',
					label: '分类一',
					render: () => {
						return (
							<span>
								<i class="erpfont icon-info-circle" />
								分类一
							</span>
						);
					},
				},
			],
		},
		{
			key: 'key4',
			label: '男女款',
			type: 'checkbox',
			multiple: true,
			options: [
				{
					label: '男女款',
					value: 1,
				},
				{
					label: '男女款',
					value: 2,
				},
				{
					label: '男女款',
					value: 3,
				},
				{
					label: '男女款',
					value: 4,
				},
				{
					label: '男女款',
					value: 5,
				},
				{
					label: '男女款',
					value: 6,
				},
			],
		},
		{
			key: 'key41',
			label: '男女款',
			type: 'radio',
			multiple: true,
			showExpand: true,
			options: [
				{
					label: '男女款',
					value: 1,
				},
				{
					label: '男女款',
					value: 2,
				},
				{
					label: '男女款',
					value: 3,
				},
				{
					label: '男女款',
					value: 4,
				},
				{
					label: '男女款',
					value: 5,
				},
				{
					label: '男女款',
					value: 6,
				},
			],
		},
		{
			key: 'key5',
			label: '供应商',
			type: 'select',
			options: [
				{
					label: '供应商一',
					value: 1,
				},
			],
		},
		{
			key: 'key7',
			label: '商品状态',
			type: 'checkbox',
			multiple: true,
			options: [
				{
					label: '男女款',
					value: 1,
				},
				{
					label: '男女款',
					value: 2,
				},
				{
					label: '男女款',
					value: 3,
				},
				{
					label: '男女款',
					value: 4,
				},
				{
					label: '男女款',
					value: 5,
				},
				{
					label: '男女款',
					value: 6,
				},
			],
		},
		{
			key: 'key8',
			label: '商品标签',
			type: 'select',
			options: [
				{
					label: '供应商一',
					value: 1,
				},
			],
		},
		{
			key: 'key10',
			label: '创建时间',
			type: 'date',
			multiple: true,
			componentProps: {
				format: 'YYYY/MM/DD',
			},
		},
		{
			key: 'key11',
			label: '创建时间',
			type: 'date',
			multiple: true,
			placeholder: ['开始时间', '结束时间'],
			componentProps: {
				format: 'YYYY/MM/DD',
			},
		},
		{
			key: 'custom',
			label: '自定义',
			type: 'custom',
			component: 'custom',
			options: [],
			showExpand: true,
		},
	],
};

头部筛选过滤表单

表单数据模型
{
  "key1": "",
  "key4": [],
  "key10": [],
  "key11": [],
  "key7": [],
  "rangeNumber": []
}

标签宽度

css
.filter-form {
	--label-width: 80px;
}
vue
<template>
	<div class="filter-form-demo">
		<FilterForm :model-value="model" :config="config" />
	</div>
	<h5 style="margin-top: 20px">表单数据模型</h5>
	<pre style="padding: 12px; margin: 12px">{{ model }}</pre>
</template>

<script setup lang="tsx">
import { reactive } from 'vue';
import { FilterForm } from '@erp/biz';
import { config } from './filter-config.tsx';

const model = reactive({
	key1: '',
	key4: [],
	key10: [],
	key11: [],
	key7: [],
	rangeNumber: [],
});
</script>

<style scoped lang="less">
.filter-form-demo {
}
</style>
tsx
import { getIndustryOptionsApi } from '@erp/biz';
import type { SearchFormI } from '@erp/biz';

export const config: SearchFormI = {
	gridProps: {
		cols: {
			xxl: 3,
			xl: 2,
			lg: 2,
			md: 2,
			sm: 2,
			xs: 2,
		},
		colGap: 12,
		rowGap: 12,
	},
	fields: [
		{
			key: 'rangeNumber',
			label: '价格',
			type: 'range-number',
			placeholder: ['最低价', '最高价'],
		},
		{
			key: 'key1',
			label: '商品名称',
			type: 'text',
			tooltip: '商品名称',
			componentProps: {
				allowClear: true,
				onFocus: evt => {
					console.log(' onFocusevt >>');
				},
				onClear(evt) {
					console.log('onClear evt >>');
				},
			},
		},
		{
			key: 'customer_industry_id',
			label: '客户行业',
			type: 'tree',
			options: () => getIndustryOptionsApi(),
			componentProps: {
				selectable: 'leaf',
				treeProps: {
					defaultExpandAll: false,
					virtualListProps: {
						height: 200,
					},
				},
			},
		},
		{
			key: 'key2',
			label: '商品编码',
			type: 'text',
		},
		{
			key: 'key3',
			label: '商品分类',
			type: 'select',
			multiple: true,
			options: [
				{
					value: '1',
					label: '<i class="erpfont icon-xianshicaigouliang" />分类一',
				},
			],
		},
		{
			key: 'key5',
			label: '供应商',
			type: 'select',
			options: [
				{
					label: '供应商一',
					value: 1,
				},
			],
		},
		{
			key: 'key8',
			label: '商品标签',
			type: 'select',
			options: [
				{
					label: '供应商一',
					value: 1,
				},
			],
		},
		{
			key: 'key10',
			label: '创建时间',
			type: 'date',
			multiple: true,
			componentProps: {
				format: 'YYYY/MM/DD',
			},
		},
		{
			key: 'key11',
			label: '创建时间',
			type: 'date',
			multiple: true,
			componentProps: {
				format: 'YYYY/MM/DD',
			},
		},
		{
			key: 'custom',
			label: '自定义',
			type: 'custom',
			component: props => {
				console.log('custom props>>', props);
				return <div style="white-space: wrap">{props.field}</div>;
			},
		},
	],
};

头部筛选过滤表单-inner

表单数据模型
{
  "key1": "",
  "key4": [],
  "key10": [],
  "key11": [],
  "key7": []
}
vue
<template>
	<div class="filter-form-demo">
		<FilterForm :model-value="model" :config="formConfig" @column-settings="handleColumnSettings" @query="handleQuery" @reset="handleQuery" />
	</div>
	<h5 style="margin-top: 20px">表单数据模型</h5>
	<pre style="padding: 12px; margin: 12px">{{ model }}</pre>
</template>

<script setup lang="tsx">
import { computed, reactive } from 'vue';
import { cloneDeep } from 'lodash-es';
import { FilterForm, pop } from '@erp/biz';
import { config } from './filter-config.tsx';

const formConfig = computed(() => {
	const cfg = cloneDeep(config);
	/**
	 * 标签在输入框里面
	 */
	cfg.labelLayout = 'inner';
	/**
	 * 查询池配置
	 */
	cfg.queryPool = 'ceshi-pool';
	return cfg;
});

const data = Array.from({ length: 8 })
	.fill(undefined)
	.map((_, index) => ({
		value: `option${index + 1}`,
		label: `Option ${index + 1}`,
	}));
const value = ['option1', 'option3', 'option5'];
const handleColumnSettings = () => {
	pop.createModal(
		import('../../modal/__demo__/columns-config.vue'),
		{
			options: data,
			value,
		},
		{ title: '列表配置' },
	)
		.then(params => {
			console.log('确认...', params);
		})
		.catch(e => {
			console.log('取消...', e);
		});
};

const model = reactive({
	key1: '',
	key4: [],
	key10: [],
	key11: [],
	key7: [],
});

const handleQuery = model => {
	console.log('handleQuery >>', model);
};
</script>

<style scoped lang="less">
.filter-form-demo {
}
</style>
tsx
import { getIndustryOptionsApi } from '@erp/biz';
import type { SearchFormI } from '@erp/biz';

export const config: SearchFormI = {
	gridProps: {
		cols: {
			xxl: 3,
			xl: 2,
			lg: 2,
			md: 2,
			sm: 2,
			xs: 2,
		},
		colGap: 12,
		rowGap: 12,
	},
	fields: [
		{
			key: 'rangeNumber',
			label: '价格',
			type: 'range-number',
			placeholder: ['最低价', '最高价'],
		},
		{
			key: 'key1',
			label: '商品名称',
			type: 'text',
			tooltip: '商品名称',
			componentProps: {
				allowClear: true,
				onFocus: evt => {
					console.log(' onFocusevt >>');
				},
				onClear(evt) {
					console.log('onClear evt >>');
				},
			},
		},
		{
			key: 'customer_industry_id',
			label: '客户行业',
			type: 'tree',
			options: () => getIndustryOptionsApi(),
			componentProps: {
				selectable: 'leaf',
				treeProps: {
					defaultExpandAll: false,
					virtualListProps: {
						height: 200,
					},
				},
			},
		},
		{
			key: 'key2',
			label: '商品编码',
			type: 'text',
		},
		{
			key: 'key3',
			label: '商品分类',
			type: 'select',
			multiple: true,
			options: [
				{
					value: '1',
					label: '<i class="erpfont icon-xianshicaigouliang" />分类一',
				},
			],
		},
		{
			key: 'key5',
			label: '供应商',
			type: 'select',
			options: [
				{
					label: '供应商一',
					value: 1,
				},
			],
		},
		{
			key: 'key8',
			label: '商品标签',
			type: 'select',
			options: [
				{
					label: '供应商一',
					value: 1,
				},
			],
		},
		{
			key: 'key10',
			label: '创建时间',
			type: 'date',
			multiple: true,
			componentProps: {
				format: 'YYYY/MM/DD',
			},
		},
		{
			key: 'key11',
			label: '创建时间',
			type: 'date',
			multiple: true,
			componentProps: {
				format: 'YYYY/MM/DD',
			},
		},
		{
			key: 'custom',
			label: '自定义',
			type: 'custom',
			component: props => {
				console.log('custom props>>', props);
				return <div style="white-space: wrap">{props.field}</div>;
			},
		},
	],
};

查询表单 API

<search-form> Props

参数名描述类型默认值
model-value (v-model)绑定值Record<string, any>function() { return {}; }
configSearchForm 动态表单配置SearchFormI-
expand展开收起booleanfalse
loading查询按钮的loadingbooleanfalse
db-click-query是否支持双击查询,点击表单 field-input 里才触发booleanfalse

<search-form> Events

事件名描述参数
reset查询组件重置model: mixed
query触发筛选model: mixed
change值改变value: mixed
field: mixed

SearchFormI

参数名描述类型默认值
fields表单字段FormFieldI[]-
components动态组件Record<string, Component>-
gridPropsgrid 布局配置,可响应式布局GridProps-
queryPool查询池
唯一标识
string-
labelLayoutlabel布局
默认左右结构
inner 为label在输入框里面
LabelLayoutType-
suffixSpansuffix 栅格占位
默认为 1,如果配置了queryPool,默认为2
number-
collapsedRows折叠时显示的行数
默认为2
number-

FormFieldI

参数名描述类型默认值
$id系统自动生成的idstring-
key数据模式key,符合property path规则string-
type组件类型InputType | 'custom'-
component组件 支持slot component jsxComponent | string | CustomFormFieldComponent-
componentProps组件配置T-
label标签的文本string-
multiple是否多值booleanfalse
disabled是否禁用boolean | Ref<boolean> | ComputedRef<boolean>-
placeholder占位string | string[]-
options组件数据配置OptionData[] | (() => Promise<OptionData[]>)-
tooltip提示内容string-
span布局宽度占位,默认位1number | ResponsiveValue-
showExpandfield 对 search-form 生效booleanfalse
slotsslots{ label?: (field: FormFieldI<T>, model: Record<string, any>) => VNodeChild; }-

CustomFormFieldComponentProps

参数名描述类型默认值
model表单数据模型Record<string, any>-
field表单字段配置FormFieldI<T>-
modelValue (v-model)当前字段对象数据值any-
options数据源OptionData[]-
loading是否加载中booleanfalse
onChangechange事件(value: any) => void-
isExpandInput是否展开input事件 labelLayout为expand有效booleanfalse
isExpandField是否展开字段 labelLayout为expand有效booleanfalse
onExpandInput是否展开input事件 labelLayout为expand有效(value: boolean) => void-
onExpandField是否展开字段 labelLayout为expand有效(value: boolean) => void-

SearchFormContextI

参数名描述类型默认值
components查询表单里的动态组件Record<string, Component>-
slots查询表单里的slotsSlots-

基于 MIT 许可发布