В библиотеке Naive UI динамические формы реализуются
с помощью компонентов <n-form> и
<n-form-item> в сочетании с реактивными структурами
данных Vue. Динамическая форма — это форма, поля которой могут
создаваться, изменяться или удаляться во время работы приложения в
зависимости от состояния данных.
Для начала создаём реактивный объект, который будет хранить данные формы:
import { reactive } from 'vue'
const formData = reactive({
fields: [
{ label: 'Имя', value: '', type: 'text' },
{ label: 'Возраст', value: '', type: 'number' }
]
})
В данном примере fields — массив объектов, каждый из
которых представляет отдельное поле формы. Ключевые свойства:
text,
number, email и др.).Используя директиву v-for, можно создавать форму
динамически:
<n-form :model="formData">
<n-form-item
v-for="(field, index) in formData.fields"
:key="index"
:label="field.label"
>
<n-input v-model="field.value" :type="field.type" />
</n-form-item>
</n-form>
Здесь v-model обеспечивает двухстороннюю привязку
данных. Любое изменение значения в поле автоматически обновляет объект
formData.
Для добавления новых полей можно использовать метод, который
модифицирует массив fields:
function addField(label, type = 'text') {
formData.fields.push({ label, value: '', type })
}
Удаление поля осуществляется с помощью метода
splice:
function removeField(index) {
formData.fields.splice(index, 1)
}
Такая структура позволяет создавать формы с переменным числом полей, добавляя или удаляя их по необходимости.
Naive UI предоставляет встроенную систему валидации через свойство
rules у <n-form>. Для динамических форм
можно формировать правила программно:
import { reactive } from 'vue'
const rules = reactive({})
formData.fields.forEach((field, index) => {
rules[`fields.${index}.value`] = [
{ required: true, message: `${field.label} обязателен` },
{ type: field.type === 'number' ? 'number' : 'string', message: `Неверный тип данных` }
]
})
Привязка правил к форме:
<n-form :model="formData" :rules="rules">
<n-form-item
v-for="(field, index) in formData.fields"
:key="index"
:label="field.label"
:path="`fields.${index}.value`"
>
<n-input v-model="field.value" :type="field.type" />
</n-form-item>
</n-form>
Это обеспечивает автоматическую проверку каждого динамического поля при отправке формы.
Динамические формы особенно удобны, когда набор полей зависит от других данных. Например, можно добавлять поля в зависимости от выбора пользователя:
function onUserTypeChange(type) {
formData.fields = [
{ label: 'Имя', value: '', type: 'text' }
]
if (type === 'employee') {
formData.fields.push({ label: 'Должность', value: '', type: 'text' })
} else if (type === 'student') {
formData.fields.push({ label: 'Группа', value: '', type: 'text' })
}
}
Такой подход позволяет создавать адаптивные формы, которые изменяются в реальном времени в зависимости от контекста.
Для более сложных форм возможно использование динамических
компонентов внутри <n-form-item> с помощью
<component :is="">:
<n-form-item
v-for="(field, index) in formData.fields"
:key="index"
:label="field.label"
>
<component :is="field.component" v-model="field.value" v-bind="field.props" />
</n-form-item>
Это позволяет интегрировать селекты, переключатели, чекбоксы и любые другие компоненты Naive UI, сохраняя при этом динамическую генерацию.
После того как все поля заполнены, данные формы легко получить через
реактивный объект formData. Для отправки можно использовать
метод validate формы:
const formRef = ref(null)
async function submitForm() {
try {
await formRef.value.validate()
console.log('Данные формы:', formData)
} catch (err) {
console.error('Ошибка валидации:', err)
}
}
Вместе с динамическими правилами валидации это обеспечивает полную безопасность и контроль над вводом данных.
Для крупных проектов с множеством динамических форм рекомендуется:
computed)
для зависимых полей, чтобы избежать избыточных перерендеров;:key в v-for для
корректного отслеживания динамических элементов при добавлении и
удалении.Такой подход позволяет создавать масштабируемые, гибкие формы, полностью интегрированные с экосистемой Naive UI.