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

В этой статье я покажу вам шаг за шагом, как создавать такие формы с помощью Vue.js.

Шаг 1. Создайте новый проект Vue под названием MultiStepForm. Прочтите настройку Vue Project здесь.

vue create MultiStepForm

Шаг 2: в папке компонентов создайте компонент Vue и назовите его Multiform.vue. Разделите его на три части: шаблон, скрипты и стили.

<template></template>
<script></script>
<style></style>

Шаг 3: внутри тегов шаблона создайте тег ‹article /› внутри тега ‹div /›. Внутри тега ‹article /› добавьте тег ‹header /› и тег ‹section /›.

<template>
 <div>
  <article>
    <header></header>
    <section></section>
   </article>
 </div>
</template>

Шаг 4: Внутри раздела заголовка добавьте тег ‹div› и с помощью v-bind добавьте динамический класс. Этот класс CSS будет зависеть от положения формы.

Затем, используя v-for, выполните цикл по массиву formGroup. Эта formGroup будет определена позже в разделе скрипта.

<header>
     
     <div
       :class="{'active':index === formPosition}"
       v-for="(step, index) in formGroup"
       :key="'step'+index"
     >
       {{ index + 1 }}
     </div>
     
</header>

Шаг 5: В теге ‹section› добавьте динамический класс с помощью v-bind. Затем с помощью директивы v-for пропустите поля formGroup.

<section :class="animation">
     <h2>{{ formGroup[formPosition].title }}</h2>
     <div>
     <div
       v-for="(field, index) in formGroup[formPosition].fields"
       :key="'field'+index"
     >
   <input type="text" v-model="field.value"  required>
      <label>{{ field.label }}</label>
     </div>
     </div>
   <div>
</div>
   </div>
</section>

Шаг 6. Под тегом ввода добавьте две кнопки. Эти кнопки будут отображаться условно в зависимости от formPosition. Для этого будет использоваться директива v-if.

<section :class="animation">
     <h2>{{ formGroup[formPosition].title }}</h2>
     <div>
     <div
       v-for="(field, index) in formGroup[formPosition].fields"
       :key="'field'+index"
     >
<input type="text" v-model="field.value"  required>
      <label>{{ field.label }}</label>
     </div>
     </div>
   <div>
<button 
     v-if="formPosition +1 < formGroup.length -1"      @click="nextStep">
     Next
   </button>
<button 
     v-if="formPosition +1 === formGroup.length -1">
    Enter
   </button>
</div>
   </div>
</section>

Последний раздел шаблона будет выглядеть так, как показано ниже.

<template>
 <div>
  <article>
    <header>
     
     <div
       :class="{'active':index === formPosition}"
       v-for="(step, index) in formGroup"
       :key="'step'+index"
     >
       {{ index + 1 }}
     </div>
     
    </header>
<section :class="animation">
     <h2>{{ formGroup[formPosition].title }}</h2>
     <div>
     <div
       v-for="(field, index) in formGroup[formPosition].fields"
       :key="'field'+index"
     >
<input type="text" v-model="field.value"  required>
      <label>{{ field.label }}</label>
     </div>
     </div>
   <div>
<button 
     v-if="formPosition +1 < formGroup.length -1"      @click="nextStep">
     Next
   </button>
<button 
     v-if="formPosition +1 === formGroup.length -1">
    Enter
   </button>
</div>
   </div>
</section>
   </article>
   </div>
</template>

Шаг 7. В теге ‹script› добавьте два свойства к объекту данных. Первый - это formPosition, который будет увеличиваться каждый раз при нажатии кнопки Далее.

Второй будет анимацией, в которой будет храниться имя класса CSS.

<script>
  export default {
  data: () => {
    return {
             formPosition: 0,
             animation: 'animate-in',
             
  }}}
</script>

Шаг 7: Затем добавьте еще одно свойство с именем formGroup, которое будет содержать данные для отображения в полях формы при переходе.

<script>
  export default {
  data: () => {
    return {
             formPosition: 0,
             animation: 'animate-in',
             formGroup: [
               {title: "Personal Details",
                 fields: [
                   {label: "First Name", value: "" },
                   {label: "Second Name", value: ""},
                   {label: "Age", value: ""},]},
               {title: "Address",
                 fields: [
                   {label: "City", value: ""},
                   {label: "Zip Code", value: ""},
                   {label: "County", value: ""},
                   {label: "State", value: ""},]},
               {title: "Academic Details",
                 fields: [
                   {label: "Academic qualification", value: ""},
                   {label: "College Attended", value: ""},
                   {label: "Year of completion", value: ""},]},
                ]}},
methods: {
     nextStep(){
      this.animation = 'animate-out';
      setTimeout(() => {
      this.animation = 'animate-in';
      this.formPosition += 1;
     }, 600);
     },}
</script>

Шаг 8: Затем добавьте метод, который изменит имя класса CSS для отображения следующей группы форм.

methods: {
     nextStep(){
      this.animation = 'animate-out';
      setTimeout(() => {
      this.animation = 'animate-in';
      this.formPosition += 1;
     }, 600);
     },}}

Затем добавьте стили CSS.

<style>
.animation-in {
   transform-origin: left;
   animation: in .6s ease-in-out;
}
.animation-out {
   transform-origin: bottom left;
   animation: out .6s ease-in-out;
}
</style>

Последний компонент Multiform.vue должен выглядеть следующим образом.

<template>
 <div>
  <article>
    <header>
     
     <div
       :class="{'active':index === formPosition}"
       v-for="(step, index) in formGroup"
       :key="'step'+index"
     >
       {{ index + 1 }}
     </div>
     
    </header>
    <section :class="animation">
     <h2>{{ formGroup[formPosition].title }}</h2>
     <div>
     <div
       v-for="(field, index) in formGroup[formPosition].fields"
       :key="'field'+index"
     >

      <input type="text" v-model="field.value"  required>
      <label>{{ field.label }}</label>
     </div>
     </div>
   <div>
   <button 
     v-if="formPosition +1 < formGroup.length -1"      @click="nextStep">
     Next
   </button>
   <button 
     v-if="formPosition +1 === formGroup.length -1">
    Enter
   </button>

   </div>
   </div>
   </section>
   </article>
   </div>
</template>
<script>
  export default {
  data: () => {
    return {
             formPosition: 0,
             animation: 'animate-in',
             formGroup: [
               {title: "Personal Details",
                 fields: [
                   {label: "First Name", value: "" },
                   {label: "Second Name", value: ""},
                   {label: "Age", value: ""},]},
               {title: "Address",
                 fields: [
                   {label: "City", value: ""},
                   {label: "Zip Code", value: ""},
                   {label: "County", value: ""},
                   {label: "State", value: ""},]},
               {title: "Academic Details",
                 fields: [
                   {label: "Academic qualification", value: ""},
                   {label: "College Attended", value: ""},
                   {label: "Year of completion", value: ""},]},
                ]}},
  methods: {
     nextStep(){
      this.animation = 'animate-out';
      setTimeout(() => {
      this.animation = 'animate-in';
      this.formPosition += 1;
     }, 600);
     },}}
</script>
<style>
.animation-in {
   transform-origin: left;
   animation: in .6s ease-in-out;
}
.animation-out {
   transform-origin: bottom left;
   animation: out .6s ease-in-out;
}
</style>

Шаг 10. Наконец, импортируйте компонент MultiForm.vue в App.vue.

<template>
  <div>
   <MultiForm/>
  </div>
</template>
<script>
import MultiForm from './components/MultiForm.vue'
export default {
   name: 'App',
   components: {
     MultiForm
 }
}
<script/>
<style></style>

Запустите приложение

И вот оно. Надеюсь, вы нашли это полезным. Я вернусь с более интересными статьями. Спасибо за чтение.

Больше контента на plainenglish.io