Задать вопрос
@Yourgrandfather

Как организовать динамическую форму?

{
  "id": 5,
  "name": "Цена",
  "code": "1",
  "type": "toggle",
  "is_required": true,
  "can_join": true,
  "options": [
    {
      "id": 5,
      "name": "От",
      "code": "12",
      "label": ""
    },
    {
      "id": 6,
      "name": "До",
      "code": "123",
      "label": ""
    }
  ]
}

Есть такое вот значение с сервера, как правильнее сделать динамическую форму которая отрисовывается в зависимости от данных с сервера. Например выше должны отрендериться два инпута.
А может быть что надо будет отрендерить чекбокс и т.д. Я примерно понимаю как это сделать, но хочу посмотреть более профессиональное решение.

Второй вопрос, как организовать стейт менеджмент такой формы, я же не знаю сколько полей будет и какие ключи у них будут.
  • Вопрос задан
  • 113 просмотров
Подписаться 1 Средний Комментировать
Решения вопроса 2
Для динамического рендеринга по схеме, где данными описано, что рендерить, в целом достаточного просто циклом пройтись по этим данным и вывести нужный компонент через динамический компонент.

```html

{{ specification.name }}
:is="componentForFormElement[specification.type]"
:id="some-generated-id"
v-model="results[specification.name]"
:required="specification.is_required"
:options="specification.options"
/>

```

Конкретный вид будет зависеть от того, что у вас есть для вывода элементов формы, но общая идея - динамически выводить нужный компонент, в зависимости от `type`. Самое удобное, если для каждого типа есть свой компонент. и они имеют одинаковый интерфейс, чтобы им можно было одинакового передать параметры.

Если компонентов нет, можно сделать и топорно - прямо ифами в шаблоне определять, как рендерить в зависимости от типа.

По второму вопросу - можно сделать объект, где ключ - имя поля формы (правда, у вас будто нет поля в описании для этого, потому я использовал name), а значение - значение элемента формы по этому имени.
Ответ написан
0xD34F
@0xD34F Куратор тега Vue.js
Метаданные формы - массив объектов, содержащих имя поля, имя компонента, с которым будет взаимодействовать пользователь, объект параметров для компонента:

const formMeta = ref([
  {
    name: '...',
    component: '...',
    props: { ... },
  },
  ...
]);

Данные формы - объект, в качестве ключей будут выступать значения свойств name элементов formMeta. Изначально можно сделать пустым: const formData = ref({});. Можно явно задать начальные значения:

const formData = ref({
  имяПоля1: значение1,
  имяПоля2: значение2,
  ...
});

Или есть вариант доставать ключи и дефолтные значения из метаданных:

const formData = ref(Object.fromEntries(formMeta.value.map(n => [
  n.name,
  n.defaultValue ?? null,
])));

На основе formMeta создаётся форма, через v-model свойства formData связываются с экземплярами компонентов:

<form>
  <div v-for="n in formMeta">
    <component
      :is="components[n.component]"
      v-model="formData[n.name]"
      v-bind="n.props"
    />
  </div>
</form>

Вот как-то так.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы