- Encapsulated based on NForm
Basic Usage
<template>
<FormPro ref="formPro" v-model="modelValue" :form-config="formConfig">
<template #operation>
<n-flex>
<n-button type="primary" @click="submit">Submit</n-button>
<n-button @click="reset">Reset</n-button>
</n-flex>
</template>
</FormPro>
</template>
<script lang="ts" setup>
/** Form field types */
interface FormFields {
name?: string;
age?: number;
}
/** Form configuration */
const formConfig: FormPro.FormItemConfig[] = [
{ name: "name", label: "Name" },
{ name: "age", label: "Age", component: "number" },
];
/** Form data */
const modelValue = ref<FormFields>({});
/** Form instance */
const formProRef = useTemplateRef("formPro");
/** Submit */
const submit = async () => {
await formProRef.value?.validate(); // Validate
console.log("Form submitted:", modelValue.value);
};
const reset = () => formProRef.value?.reset();
</script>Form Validation
- Pass
rulesinform-propsto enable form validation. - Supports all
Form Propsparameters exceptmodel.
<template>
<FormPro
ref="formPro"
v-model="modelValue"
:form-config="formConfig"
:form-props="formProps"
>
...
</FormPro>
</template>
<script lang="ts" setup>
import { type FormProps } from "naive-ui";
/** Form validation */
const formProps: FormProps = {
rules: {
name: [{ required: true, message: "Please enter your name" }],
age: [{ required: true, message: "Please enter your age" }],
},
};
</script>Form Item Configuration
You can configure props, slots, and formItemProps for each form item individually.
⚠️ Note
props and slots depend on the component you use.
- If
componentis not set, the default isNInput's Input-Props and Input-Slots. - If
componentis set toselect, only NSelect props and slots are available. - Even if you don't know what configurations are available for each component's
propsandslots, you don't need to worry as there will be TS prompts. If code prompts don't appear, simply type"to list all available properties. Or visit the Naïve UI official website to view them.
formItemProps accepts all FormItem and GridItem props except path, span, and label.
/** Form configuration */
const formConfig: FormPro.FormItemConfig[] = [
{
name: "name",
label: "Name",
props: {
// Custom attribute
placeholder: "Please enter your name",
},
// Render slots
slots: {
// prefix: () => <NEl>😁</NEl>, // Using tsx
prefix: () => [h(NEl, {}, () => "😁")],
suffix: () => [h("span", null, "😎")],
},
// Form item configuration
formItemProps: {
showFeedback: false,
},
},
{ name: "age", label: "Age", component: "number" },
];Dynamic Data
In some cases, such as when options are fetched from an API, you can use computed to return the configuration.
import { type SelectOption } from "naive-ui";
onMounted(async () => {
loading.value = true;
options.value = await asyncOptions();
loading.value = false;
});
/** Default options */
const options = ref<SelectOption[]>([{ label: "Eat", value: 1 }]);
/** Option loading state */
const loading = ref(false);
/** Simulate fetching dynamic options */
const asyncOptions = () => {
return new Promise<SelectOption[]>((resolve) =>
setTimeout(
() =>
resolve([
{ label: "Eat", value: 1 },
{ label: "Sleep", value: 2 },
{ label: "Play games", value: 3, disabled: true },
]),
2000
)
);
};
/** Form configuration */
const formConfig = computed((): FormPro.FormItemConfig[] => [
{
name: "hobby",
label: "Hobby",
component: "select",
props: {
multiple: true, // Enable multiple selection
loading: loading.value, // Loading state
options: options.value, // Dynamic options
},
},
]);Dynamic Show/Hide
If you need to show or hide a form item based on certain conditions, use the hidden property.
/** Form data */
const modelValue = ref<FormFields>({
age: 18,
});
/** Form configuration */
const formConfig = computed((): FormPro.FormItemConfig[] => [
{ name: "age", label: "Age", component: "number" },
{
name: "hobby",
label: "Hobby",
component: "select",
hidden: modelValue.value.age <= 18,
props: {
multiple: true, // Enable multiple selection
loading: loading.value, // Loading state
options: options.value, // Dynamic options
},
},
]);Using Dictionary
If you need to use dictionary data as a data source, add the dict property to the form item configuration and specify the dictionary key. The data source will be automatically fetched from the dictionary.
⚠️ Note
Currently, only select, radio, and checkbox components support dictionaries.
If the options property is set in props, the dict property will be ignored.
/** Form configuration */
const formConfig: FormPro.FormItemConfig[] = [
{
name: "sex",
label: "Gender",
component: "select",
dict: "gender", // Use dictionary
},
];Using Slots
If you need to use custom slots for rendering, you can do so as follows:
💡 Note
- The slot name must match the
nameproperty in theform-config. - Slot content takes priority and will override the
componentproperty.
<template>
<FormPro v-model="modelValue" :form-config="formConfig">
<!-- Custom slot -->
<template #name>Custom content</template>
</FormPro>
</template>
<script lang="ts" setup>
const formConfig: FormPro.FormItemConfig[] = [
{
name: "name",
label: "Name",
// The component property is ignored when using a slot
component: "input",
},
];
</script>Custom Component
- Some users may ask: "What if I want to render my own custom component?"
- Of course you can!
💡 Note
The component property can accept not only basic component types, but also a function that returns a component, or you can directly pass a component object.
/** Simple component to render msg info */
const MyComponent = defineComponent({
props: {
msg: { type: String, default: "Default message" },
},
setup(props) {
return () => h("div", props.msg);
},
});
/** Form configuration */
const formConfig: FormPro.FormItemConfig[] = [
{
name: "msg",
label: "Message",
// component: () => <MyComponent msg="hello" />, // Using tsx
component: () => h(MyComponent, { msg: "hello" }), // Using h function
},
];Props
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| v-model or model-value | object | No | Form binding data | |
| operation-span | number | No | 4 | Operation column width |
| form-config | FormItemConfig[] | No | Form item configuration | |
| form-props | FormProps | No | see below | Form properties (except model) |
| grid-props | GridProps | No | see below | Form layout properties |
form-propsdefault:{ labelPlacement: "left", labelWidth: 80 }grid-propsdefault:{ xGap: 16 }
FormItemConfig
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| name | string | Yes | Field name | |
| label | string | No | Label (not shown if not set) | |
| span | number | No | 4 | Grid width |
| dict | string | No | Dictionary | |
| hidden | boolean | No | false | Whether hidden |
| label-message | string | No | Tip message | |
| label-reverse | boolean | No | false | Reverse label layout |
| block-message | string | No | Block message | |
| component | component Type | No | input | Component |
| props | component Props | No | {} | Component props |
| slots | component Slots | No | {} | Component slots |
| form-item-props | FormItemGi Props | No | {} | FormItemGi props |
💡 Note
label-reversedefaults tofalse, with the prompt information in front and the label behind; whentrue, the prompt information is behind and the label is in front.block-messagesupports bothComponentand() => VNodetypes. This configuration is invalid in TablePro for aesthetic reasons, please uselabel-messageinsteadform-item-propsexcludespath,label, andspanproperties.
Component Types
Supported component types:
inputInputtextareaTextareanumberNumber inputpasswordPassword inputselectSelectradioRadio groupradio-buttonRadio button groupcheckboxCheckbox groupdateDate pickertimeTime pickerswitchSwitchtree-selectTree selectcolor-pickerColor pickersliderSlidertextPlain textComponentCustom component() => VNodeCustom component
Component Props and Slots
| Component | Props | Slots |
|---|---|---|
input textarea password | Input Props | Input Slots |
select | Select Props | Select Slots |
radio radio-button | RadioGroup Props | undefined |
checkbox | Checkbox Props | Checkbox Slots |
date | DatePicker Props | DatePicker Slots |
time | TimePicker Props | TimePicker Slots |
switch | Switch Props | Switch Slots |
tree-select | TreeSelect Props | TreeSelect Slots |
color-picker | ColorPicker Props | ColorPicker Slots |
slider | Slider Props | Slider Slots |
text | Text Props | Text Slots |
Slots
| Name | Params | Description |
|---|---|---|
| operation | () | Operation area buttons |
| [name] | () | Form item slot |
Expose
| Name | Type | Description |
|---|---|---|
| validate | () => Promise<void> | Trigger validation |
| reset | () => void | Reset form |
nuyoah