Здесь я покажу вам, как создать простой конструктор форм, который запускается из файла JSON.

Слишком часто люди слишком усложняют формы. По этой причине я начал использовать конструктор форм в большинстве своих проектов. Вот как создать быстрый и надежный конструктор форм с использованием vue.js.

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

Обратите внимание, что в этом руководстве я использую Bootstrap в качестве библиотеки CSS.

Первый ввод: Текст

<template>
  <div 
    class="form-group" 
    :class="{ field.cols ? `cols-md-${field.cols}` : '' }"
  >
    <label :for="field.name">{{ field.label }}</label>
    <input 
      type="text" 
      class="formcontrol"
      :id="field.name"
      :name="field.name" 
      v-model="data[field.prop]"
    >
  </div>
</template>
<script>
  export default {
    props: { field: object, data: Object }
  }
</script>

Теперь скопируем это, чтобы создать поле число:

<template>
  <div 
    class="form-group" 
    :class="{ field.cols ? `cols-md-${field.cols}` : '' }"
  >
    <label :for="field.name">{{ field.label }}</label>
    <input 
      type="number" 
      class="form-control"
      :id="field.name"
      :name="field.name" 
      v-model="data[field.prop]"
    >
  </div>
</template>
<script>
  export default {
    props: { field: object, data: Object }
  }
</script>

И, наконец, наше поле select будет выглядеть примерно так:

<template>
  <div 
    class="form-group" 
    :class="{ field.cols ? `cols-md-${field.cols}` : '' }"
  >
    <label :for="field.name">{{ field.label }}</label>
    <select 
      class="form-control"
      :id="field.name"
      :name="field.name" 
      v-model="data[field.prop]"
    >
      <option 
        v-for="(option, key) in field.options"
        :key="key"
        :value="option.value"
      >
        {{ option.text }}
      </option>
    </select>
  </div>
</template>
<script>
  export default {
    props: { field: object, data: Object }
  }
</script>

Теперь, когда у нас есть три компонента ввода, которые мы хотим использовать, все, что нам нужно сделать, это создать компонент формы. Все, что нам нужно сделать, это создать макет и быть фактической оболочкой формы для всех наших полей ввода.

<template>
  <form>
    <div 
      class="form-row"
      v-for="(row, rKey) in rows"
      :key="`r-${rKey}`"
    >
      <component 
        v-for="(col, cKey) in row.cols"
        :key="`r-${rKey}-c-${cKey}`"
        :is="'f-' + col.type"
        :field="col"
        :data="data"
      >
    </div>
    <button type="submit" class="btn btn-primary">Submit</button
  </form>
</template>
<script>
  import text from './text';
  import number from './number';
  import select from './select';
  export default {
    props: { rows: Array, data: Object },
    components: {
      'f-text': text,
      'f-number': number,
      'f-select': select
    }
  }
</script>

Не стоит слишком сильно разочаровываться в компоненте формы, мы просто сделали его немного интереснее, добавив возможность использовать строки и столбцы, чтобы наши формы имели немного лучшую функциональность макета. Когда мы сложим все воедино, все станет намного понятнее.

Чтобы фактически отобразить это, нам нужно определить макет формы как объект JSON. В этом примере мы создадим форму, которая собирает данные пользователя со следующими полями: имя, фамилия, возраст и пол. Вот как мы его структурируем:

[
  {
    "cols": [
      {
        "cols": 6,
        "type": "text",
        "prop": "firstname",
        "name": "firstname",
        "label": "First name"
      },
      {
        "cols": 6,
        "type": "text",
        "prop": "lastname",
        "name": "lastname",
        "label": "Last name"
      }
    ]
  },
  {
    "cols": [
      {
        "cols": 6,
        "type": "number",
        "prop": "age",
        "name": "age",
        "label": "Age"
      },
      {
        "cols": 6,
        "type": "select",
        "prop": "gender",
        "name": "gender",
        "label": "Gender",
        "options": [
          {
            value: "male",
            text: "Male"
          },
          {
            value: "female",
            text: "Female"
          }
        ]
      }
    ]
  }
]

Вот и все самое сложное! У вас официально есть многоразовый конструктор форм, который можно использовать в любом проекте. Чтобы реализовать это, все, что вам нужно сделать, это импортировать конструктор форм, а также ваш объект JSON, а затем подключить их.

<template>
  <form-builder
    :rows="config"
    :data="data"
  >
  </form-builder>
</template>
<script>
  import formBuilder from './form-builder.js';
  import config from './user-data.json';
  export default {
    data() {
      return {
        config: config,
        data: {
          firstname: '',
          lastname: '',
          age: 0,
          gender: ''
        }
      }
    },
    components: {
      'form-builder': formBuilder
    }
  }
</script>

Теперь, когда вам нужно добавить какие-либо поля в форму, это всего лишь случай обновления вашего файла JSON. Одна из моих любимых вещей в этом подходе заключается в том, что очень легко согласовываться с моими формами, и любая дополнительная логика, которую мне нужно добавить, может выполняться непосредственно через конструктор форм.

В целях этого руководства я не включил метод для фактической отправки формы, потому что это будет зависеть от вашей реализации. Например, вы можете указать свойство действия в построителе форм или предоставить метод обратного вызова при отправке формы. Дайте мне знать, если вы хотите большей ясности по этому поводу.