Предисловие

В этом посте представлены наши решения для форм @ femessage / el-form-renderer, показывающие, как мы решаем проблемы с формами с помощью vue.js:

  • Элементы формы динамически отображаются или скрываются
  • Связывание данных формы
  • Форматирование входных / выходных данных формы
  • Разработка элементов пользовательской формы
  • Проверка сложной формы

Решения

Элементы формы динамически отображаются или скрываются

Использование hidden для управления отображением или скрытием элемента формы.

<template>
  <el-form-renderer ref="form" :content="content" />
</template>
<script>
export default {
  name: 'hidden',
  data() {
    return {
      content: [
        {
          type: 'select',
          id: 'selected',
          label: 'Select Item',
          options: [
            {
              label: 'Option A',
              value: 'optionA'
            },
            {
              label: 'Option B',
              value: 'optionB'
            }
          ]
        },
        {
          label: 'Data',
          type: 'input',
          id: 'data',
          el: {
            placeholder: 'content about Option B'
          },
          hidden: form => form.selected !== 'optionB' // hidden if you selected option B
        },
      ]
    }
  }
}
</script>

Связывание данных формы (включено)

Использование on для привязки blur, focus и других событий для достижения связи данных формы.

Например, автоматическое заполнение lastName после ввода fullName

<template>
  <el-form-renderer ref="form" :content="content" />
</template>
<script>
export default {
  data() {
    return {
      content: [
        {
          label: 'fullname',
          type: 'input',
          id: 'fullName',
          on: {
            blur: ([event], updateForm) => {
              const value = event.target.value
              const lastName = value.split(' ')[1] // split value by space
              updateForm({ lastName })             // update Form
            },
          },
        },
        {
          label: 'lastname',
          type: 'input',
          id: 'lastName',
        }
      ]
    }
  }
}
</script>

Форматирование ввода / вывода (inputFormat / outputFormat)

В качестве примера возьмем средство выбора диапазона дат. Выходным значением этого компонента является строка, но для внутреннего API требуется два поля {startDate, endDate}. На этом этапе данные необходимо отформатировать.

InputFormat

Преобразование данных backend api в ожидаемый формат компонента

<script>
export default {
  data() {
    return {
      content: [
        {
          el: {
            type: 'daterange',
            placeholder: 'select date',
            valueFormat: 'yyyy-MM-dd'
          },
          type: 'date-picker',
          id: 'date',
          label: 'Date',
          // input data: startDate: '2019-07-23', endDate:'2019-07-24'
          // after formatting: [ '2019-07-23', '2019-07-24' ]
          inputFormat: row => ([row.startDate, row.endDate])
        }
      ]
    }
  }
}
</script>

Формат вывода

Преобразование выходных данных в ожидаемый формат backend api

<script>
export default {
  data() {
    return {
      content: [
        {
          el: {
            type: 'daterange',
            placeholder: 'select date',
            valueFormat: 'yyyy-MM-dd'
          },
          type: 'date-picker',
          id: 'date',
          label: '日期', 
          // component data: date: [ '2019-07-23', '2019-07-24' ]
          // after formatting: {startDate: '2019-07-23', endDate: '2019-07-24'}
          outputFormat: (val) => {
            if (!val) {
              return {startDate: '', endDate: ''}
            }
            return {
              startDate: val[0],
              endDate: val[1]
            }
          }
        }
      ]
    }
  }
}
</script>

Разработка элементов пользовательской формы (компонент)

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

component может отображать пользовательский компонент, и ключевым моментом написания пользовательского компонента является реализация v-модели внутри компонента:

  • значение имени реквизита
  • испустить событие ввода

Вот пример

<!-- 自定义组件 my-input -->
<input :value="value" @input="onInput">
<script>
export default {
  props: {
    value: String
  },
  methods: {
    onInput(val) {
      this.$emit('input', 'my-input: ' + val)
    }
  }
}
</script>

Теперь @ femessage / el-form-renderer может отображать этот пользовательский компонент ввода с помощью параметра component.

<template>
  <el-form-renderer :content="content"/>
</template>
<script>
import MyInput from '@/components/my-input.vue'
export default {
  data() {
    return {
      content: [
        {
          // rendering MyInput
          component: MyInput,
          id: 'myInput',
          label: 'label'
        }
      ]
    }
  },
}
</script>

Вот список компонентов, которые мы можем использовать @ femessage / el-form-renderer для рендеринга без написания шаблона.

Проверка сложной формы (правила)

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

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

Вот пример, показывающий, как пользовательский компонент (базовый ввод) устанавливает следующие правила проверки:

  • Нулевые значения не допускаются
  • Необходимо ввести не менее 3 цифр
  • Должен начинаться с 123

<template>
  <el-input :value="value" @input="onInput"/>
</template>
<script>
export default {
  rules() {
    return [
      {
        required: true,
        validator: (rule, val, callback) => {
          if (!val) {
            callback(new Error('is required!'))
          } else if (!val.length >= 3) {
            callback(new Error('must input at least 3 number!'))
          } else if (!/^123/.test(val)) {
            callback(new Error('must start with 123!'))
          } else {
            callback()
          }
        }
      }
    ]
  },
  props: ['value'],
  methods: {
    onInput(val) {
      this.$emit('input', val)
    }
  }
}
</script>

Заключение

Мы используем @ femessage / el-form-renderer в каждой команде и в каждом проекте. Подробнее читайте в github.

Приглашаем всех использовать его для ускорения роста производительности ~