Value Format Conversion
Bind custom converters to form components to handle special data formats or conversion logic. Converters enable bidirectional data conversion: converting backend data to form display format (forward), and converting form data to backend required format (reverse).
Converter Overview
Converters provide two conversion methods:
toFormValue: Forward conversion, converts backend data to values displayed by form componentstoValue: Reverse conversion, converts form component values to data format submitted to backend
Usage Scenarios
Converters are suitable for the following scenarios:
- Data format conversion (e.g., string and array interconversion)
- Data cleaning (e.g., removing spaces, formatting)
- Data type conversion (e.g., string and number interconversion)
- Complex data structure processing
Quick Start
1. Mount Converter
Globally mount the converter in main.js
import {formCreate} from '/path/to/fcDesignerPro/dist/index.es.js'
formCreate.parser({
name: 'input',
merge: true,
toFormValue(val) {
return (val || '').trim()
},
toValue(val) {
return (val || '').trim()
},
})2. Use Converter
Converters will automatically trigger in the following scenarios:
- Form echo: Calls
toFormValueto convert backend data to form display values - Form submission: Calls
toValueto convert form values to submission data
<template>
<form-create v-model="formData" :rule="rule" v-model:api="fApi" @submit="handleSubmit"></form-create>
</template>
<script setup>
import {ref} from 'vue';
import {formCreate} from '/path/to/fcDesignerPro/dist/index.es.js'
const formData = ref({});
const fApi = ref(null);
const rule = ref([
{
type: 'input',
field: 'username',
title: 'Username',
}
]);
function handleSubmit(formData) {
// At this point formData.username has been processed through toValue, removing leading and trailing spaces
console.log('Submission data:', formData);
}
</script>Complete Examples
Example 1: Remove Leading and Trailing Spaces from Input
Automatically remove leading and trailing spaces from input component values to ensure clean data.
import {formCreate} from '/path/to/fcDesignerPro/dist/index.es.js'
formCreate.parser({
name: 'input',
merge: true,
// Forward conversion: convert from backend data to form display value
toFormValue(val) {
// If value is null or undefined, return empty string
if (val == null) {
return '';
}
// Remove leading and trailing spaces
return String(val).trim();
},
// Reverse conversion: convert from form value to submission data
toValue(val) {
// Also remove leading and trailing spaces on submission
if (val == null) {
return '';
}
return String(val).trim();
},
});Usage Scenario:
<template>
<form-create v-model="formData" :rule="rule" v-model:api="fApi"></form-create>
</template>
<script setup>
import {ref, onMounted} from 'vue';
const formData = ref({});
const fApi = ref(null);
const rule = ref([
{
type: 'input',
field: 'username',
title: 'Username',
}
]);
// Simulate loading data from backend (contains leading and trailing spaces)
formData.value = {
username: ' admin ' // Contains leading and trailing spaces
};
// When form echoes, toFormValue will automatically remove spaces, displaying as 'admin'
function handleSubmit(data) {
// User inputs ' test ', toValue will automatically convert to 'test' on submission
console.log(data.username); // Output: 'test'
}
</script>Example 2: Convert Checkbox Values to Comma-Separated String
Convert checkbox component array values to comma-separated strings for easier backend storage and processing:
import {formCreate} from '/path/to/fcDesignerPro/dist/index.es.js'
formCreate.parser({
name: 'checkbox',
merge: true,
// Forward conversion: convert from backend string to form array
toFormValue(val) {
if (!val) {
return [];
}
// If string, split by comma and convert to array
if (typeof val === 'string') {
return val.split(',').map(item => item.trim()).filter(item => item);
}
// If already array, return directly
if (Array.isArray(val)) {
return val;
}
return [];
},
// Reverse conversion: convert from form array to submission string
toValue(val) {
if (!val || !Array.isArray(val)) {
return '';
}
// Convert array to comma-separated string
return val.filter(item => item).join(',');
},
});Usage Scenario:
<template>
<form-create v-model="formData" :rule="rule" v-model:api="fApi" @submit="handleSubmit"></form-create>
</template>
<script setup>
import {ref, onMounted} from 'vue';
const formData = ref({});
const fApi = ref(null);
const rule = ref([
{
type: 'checkbox',
field: 'hobbies',
title: '兴趣爱好',
options: [
{label: '阅读', value: 'reading'},
{label: '运动', value: 'sports'},
{label: '音乐', value: 'music'},
{label: '旅行', value: 'travel'},
]
}
]);
// Simulate loading data from backend (string format)
formData.value = {
hobbies: 'reading,sports,music' // Backend stores as string
};
// When form echoes, toFormValue automatically converts to array ['reading', 'sports', 'music']
function handleSubmit(data) {
// User selected ['reading', 'travel'], toValue automatically converts to 'reading,travel' on submission
console.log(data.hobbies); // Output: 'reading,travel'
// Can directly submit to backend without additional processing
}
</script>Example 3: Number Formatting
Convert string numbers to number type, or maintain number format. Suitable for scenarios where input box string values need to be converted to number type for backend submission:
import {formCreate} from '/path/to/fcDesignerPro/dist/index.es.js'
formCreate.parser({
name: 'input',
merge: true,
// Forward conversion: ensure display as string (form components require)
toFormValue(val) {
if (val == null) {
return '';
}
// If number, convert to string for display
return String(val);
},
// Reverse conversion: convert to number type for submission
toValue(val) {
if (val === '' || val == null) {
return null;
}
// Convert to number
const num = Number(val);
// If conversion fails, return original value
return isNaN(num) ? val : num;
},
});Usage Scenario:
<template>
<form-create v-model="formData" :rule="rule" v-model:api="fApi" @submit="handleSubmit"></form-create>
</template>
<script setup>
import {ref} from 'vue';
const formData = ref({});
const fApi = ref(null);
const rule = ref([
{
type: 'input',
field: 'price',
title: '商品价格',
props: {
type: 'number',
placeholder: '请输入价格'
}
},
{
type: 'input',
field: 'quantity',
title: '库存数量',
props: {
type: 'number',
placeholder: '请输入数量'
}
}
]);
// Simulate loading data from backend (number type)
formData.value = {
price: 99.99, // Backend returns number type
quantity: 100 // Backend returns number type
};
// When form echoes, toFormValue automatically converts to strings '99.99' and '100' for display
function handleSubmit(data) {
// User input '199.50' and '50', toValue automatically converts to number type on submission
console.log(data.price); // Output: 199.5 (number type)
console.log(data.quantity); // Output: 50 (number type)
console.log(typeof data.price); // Output: 'number'
// Can directly perform math operations without manual conversion
const total = data.price * data.quantity;
console.log('Total:', total); // Output: 9975
}
</script>Example 4: Date Formatting
Handle date format conversion, converting timestamps or date strings to a unified display format. Suitable for scenarios where backend stores timestamps but form components require date objects:
import {formCreate} from '/path/to/fcDesignerPro/dist/index.es.js'
formCreate.parser({
name: 'datePicker',
merge: true,
// Forward conversion: convert backend date format to component-required format
toFormValue(val) {
if (!val) {
return null;
}
// If timestamp, convert to date object
if (typeof val === 'number') {
return new Date(val);
}
// If string, convert to date object
if (typeof val === 'string') {
return new Date(val);
}
return val;
},
// Reverse conversion: convert date object to timestamp for submission
toValue(val) {
if (!val) {
return null;
}
// If date object, convert to timestamp
if (val instanceof Date) {
return val.getTime();
}
return val;
},
});Usage Scenario:
<template>
<form-create v-model="formData" :rule="rule" v-model:api="fApi" @submit="handleSubmit"></form-create>
</template>
<script setup>
import {ref} from 'vue';
const formData = ref({});
const fApi = ref(null);
const rule = ref([
{
type: 'datePicker',
field: 'birthday',
title: '出生日期',
props: {
type: 'date',
placeholder: '请选择日期'
}
},
{
type: 'datePicker',
field: 'startTime',
title: '开始时间',
props: {
type: 'datetime',
placeholder: '请选择日期时间'
}
}
]);
// Simulate loading data from backend (timestamp format)
formData.value = {
birthday: 631123200000, // Backend returns timestamp: 1990-01-01
startTime: 1609459200000 // Backend returns timestamp: 2021-01-01 00:00:00
};
// When form echoes, toFormValue automatically converts to date objects for display
function handleSubmit(data) {
// User selected dates, toValue automatically converts to timestamps on submission
console.log(data.birthday); // Output: 631123200000 (timestamp)
console.log(data.startTime); // Output: 1609459200000 (timestamp)
console.log(typeof data.birthday); // Output: 'number'
// Can directly submit to backend without manual conversion
// Backend APIs typically receive timestamp format for easier storage and calculation
}
</script>Example 5: Using Context Information
Converter functions can receive context parameters for more complex conversion logic. Suitable for scenarios where conversion method needs to be dynamically determined based on component configuration:
import {formCreate} from '/path/to/fcDesignerPro/dist/index.es.js'
formCreate.parser({
name: 'select',
merge: true,
// Forward conversion: use context information
toFormValue(val, ctx) {
// ctx contains current rule, form data, etc.
const {prop} = ctx;
// Determine conversion method based on rule configuration
if (prop.props?.multiple) {
// Multiple selection mode: string to array
if (typeof val === 'string') {
return val.split(',').filter(item => item);
}
return Array.isArray(val) ? val : [];
} else {
// Single selection mode: return directly
return val || '';
}
},
// Reverse conversion: use context information
toValue(val, ctx) {
const {prop} = ctx;
if (prop.props?.multiple) {
// Multiple selection mode: array to string
return Array.isArray(val) ? val.join(',') : '';
} else {
// Single selection mode: return directly
return val || '';
}
},
});Usage Scenario:
<template>
<form-create v-model="formData" :rule="rule" v-model:api="fApi" @submit="handleSubmit"></form-create>
</template>
<script setup>
import {ref} from 'vue';
const formData = ref({});
const fApi = ref(null);
const rule = ref([
{
type: 'select',
field: 'category',
title: '商品分类',
props: {
multiple: false, // 单选模式
placeholder: '请选择分类'
},
options: [
{label: '电子产品', value: 'electronics'},
{label: '服装', value: 'clothing'},
{label: '食品', value: 'food'}
]
},
{
type: 'select',
field: 'tags',
title: '商品标签',
props: {
multiple: true, // 多选模式
placeholder: '请选择标签'
},
options: [
{label: '热销', value: 'hot'},
{label: '新品', value: 'new'},
{label: '推荐', value: 'recommend'}
]
}
]);
// Simulate loading data from backend
formData.value = {
category: 'electronics', // Single selection: backend returns string
tags: 'hot,new,recommend' // Multiple selection: backend returns comma-separated string
};
// When form echoes:
// - category single selection: directly displays 'electronics'
// - tags multiple selection: toFormValue automatically converts to array ['hot', 'new', 'recommend']
function handleSubmit(data) {
// After user operations, on submission:
// - category single selection: directly returns string 'clothing'
// - tags multiple selection: toValue automatically converts to string 'hot,new'
console.log(data.category); // Output: 'clothing' (string)
console.log(data.tags); // Output: 'hot,new' (string, multiple selection auto-converted)
// Same converter automatically adapts different conversion logic based on component configuration
// No need to register different converters for single and multiple selection
}
</script>Converter Method Description
toFormValue
Function: Convert backend data to form component display value
Call Timing:
- When form initializes
- When calling
fApi.reload()method - When setting form data
Parameters:
value: Backend data valuectx: Context object, containing the following properties:prop: Current component's rule configuration$api: Form API instance
Return Value: Converted form display value
toValue
Function: Convert form component value to data format submitted to backend
Call Timing:
- When form submits
- When calling
fApi.submit()method - When getting form data
Parameters:
value: Form component's current valuectx: Context object, containing the following properties:prop: Current component's rule configuration$api: Form API instance
Return Value: Converted submission data
Notes
Converter Scope: Converters are bound by component name (
name). Only one converter can be registered per component name; later registrations override earlier ones.Performance Considerations: Converters are called on every data conversion. Avoid time-consuming operations in converters.
Data Consistency: Ensure
toFormValueandtoValueare inverse operations, i.e.,toValue(toFormValue(val))should equal the original value (or equivalent value).Null Value Handling: Properly handle boundary cases like
null,undefined, and empty strings in converters.Type Safety: Pay attention to data type conversions to avoid errors caused by type mismatches.
Data Structure
type Parser = (name: string, parser: ParserConfig) => void;
interface ParserConfig {
// Whether to merge built-in parsing rules, keep true for built-in components
merge?: true;
// Forward conversion: convert backend data to form display value
toFormValue?: (value: any, ctx: ParserContext) => any;
// Reverse conversion: convert form value to submission data
toValue?: (value: any, ctx: ParserContext) => any;
}
interface ParserContext {
// Current component's rule configuration
rule: Rule;
// Form API instance
$api: Api;
}merge Parameter Description
- When adding parsers for built-in components (such as
input,select, etc.), configuremerge: trueto avoid overriding system built-in parsing logic. - Custom extended components can omit this parameter if there is no default parsing logic.
By customizing converters, you can flexibly handle various data format conversion requirements, achieving seamless integration between form data and backend data, improving development efficiency and user experience.


