查询表单
侧边栏筛选表单通用配置实例
表单数据模型
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 {}; } |
| config | SearchForm 动态表单配置 | SearchFormI | - |
| expand | 展开收起 | boolean | false |
| loading | 查询按钮的loading | boolean | false |
| db-click-query | 是否支持双击查询,点击表单 field-input 里才触发 | boolean | false |
<search-form> Events
| 事件名 | 描述 | 参数 |
|---|---|---|
| reset | 查询组件重置 | model: mixed |
| query | 触发筛选 | model: mixed |
| change | 值改变 | value: mixedfield: mixed |
SearchFormI
| 参数名 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| fields | 表单字段 | FormFieldI[] | - |
| components | 动态组件 | Record<string, Component> | - |
| gridProps | grid 布局配置,可响应式布局 | GridProps | - |
| queryPool | 查询池 唯一标识 | string | - |
| labelLayout | label布局 默认左右结构 inner 为label在输入框里面 | LabelLayoutType | - |
| suffixSpan | suffix 栅格占位 默认为 1,如果配置了queryPool,默认为2 | number | - |
| collapsedRows | 折叠时显示的行数 默认为2 | number | - |
FormFieldI
| 参数名 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| $id | 系统自动生成的id | string | - |
| key | 数据模式key,符合property path规则 | string | - |
| type | 组件类型 | InputType | 'custom' | - |
| component | 组件 支持slot component jsx | Component | string | CustomFormFieldComponent | - |
| componentProps | 组件配置 | T | - |
| label | 标签的文本 | string | - |
| multiple | 是否多值 | boolean | false |
| disabled | 是否禁用 | boolean | Ref<boolean> | ComputedRef<boolean> | - |
| placeholder | 占位 | string | string[] | - |
| options | 组件数据配置 | OptionData[] | (() => Promise<OptionData[]>) | - |
| tooltip | 提示内容 | string | - |
| span | 布局宽度占位,默认位1 | number | ResponsiveValue | - |
| showExpand | field 对 search-form 生效 | boolean | false |
| slots | slots | { label?: (field: FormFieldI<T>, model: Record<string, any>) => VNodeChild; } | - |
CustomFormFieldComponentProps
| 参数名 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| model | 表单数据模型 | Record<string, any> | - |
| field | 表单字段配置 | FormFieldI<T> | - |
| modelValue (v-model) | 当前字段对象数据值 | any | - |
| options | 数据源 | OptionData[] | - |
| loading | 是否加载中 | boolean | false |
| onChange | change事件 | (value: any) => void | - |
| isExpandInput | 是否展开input事件 labelLayout为expand有效 | boolean | false |
| isExpandField | 是否展开字段 labelLayout为expand有效 | boolean | false |
| onExpandInput | 是否展开input事件 labelLayout为expand有效 | (value: boolean) => void | - |
| onExpandField | 是否展开字段 labelLayout为expand有效 | (value: boolean) => void | - |
SearchFormContextI
| 参数名 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| components | 查询表单里的动态组件 | Record<string, Component> | - |
| slots | 查询表单里的slots | Slots | - |