[Серия Vue] Элегантно используйте vue для создания динамических форм (2)

Vue.js
[Серия Vue] Элегантно используйте vue для создания динамических форм (2)

Резюме истории:

](nuggets.capable/post/684490…)

  • [[vue series] Когда element-ui вводится по запросу и сталкивается с ленивой загрузкой маршрутизации vue-router

](nuggets.capable/post/684490…)

фон спроса

В модуле верстака необходимо утвердить новый запрос на отпуск.Когда просмотр запроса открыт, становится известно, что существует 8 типов отпуска: ежегодный отпуск, отпуск по болезни, творческий отпуск, отпуск по личным обстоятельствам, отпуск в связи со свадьбой, отпуск на похороны , отпуск по беременности и родам, отпуск по уходу за ребенком. Первая мысль Сяосяо заключается в том, что он не хочет писать несколько страниц формы, и он не хочет писать много логики суждения на одной странице формы. Поэтому я предварительно спросил, можно ли сделать динамическую форму с помощью бэкенда, ведь это было сделано когда-то раньше. Однако и серверная часть, и продукт сходятся во мнении, что изменения формы несущественны, и нет необходимости разрабатывать систему конфигурации формы. Я недоволен.После того, как обзор требований завершен, Xiaoxiao начала исследовать план реализации и выбор технологии.

Поиск технических решений и технический подбор

Размышляете о том, можно ли с этим справиться с помощью полного динамического управления формой во внешнем интерфейсе? Таким образом, время разработки и нагрузка на серверную часть могут быть сокращены.Конечно, на этот раз спрос больше на переднюю часть. Затем придумайте динамическую форму, которая может автоматически генерировать формы в соответствии с различными типами запросов на отпуск.Хотя это требует больше размышлений и дизайна в первой разработке, ее легко поддерживать позже. Сяосяо также является человеком, у которого есть требования к потребностям, бизнесу и коду. гм~

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

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

динамические компоненты

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

Подводя итоги, необходимо разработать следующие компоненты:

  • Средство выбора даты (зависит от средства выбора даты и времени mint-ui)
  • Средство выбора даты с утром и днем ​​(плагин vue-halfday-datepicker, npm для вторичного пакета средства выбора mint-ui, используемого внизу)
  • Калькулятор продолжительности отпуска (плагин для расчета дней отпуска, зависит от времени начала и окончания)
  • Автоматический калькулятор времени окончания (в зависимости от времени начала и окончания, следующего развития ~)
  • Компонент многострочного поля ввода
  • Компонент загрузки изображения (вторичная инкапсуляция для внутреннего компонента загрузки)

в请假时长计算器в авторскомИзготовление колес | Как разработать калькулятор отпусков?Подробности и детали реализации смотрите в этом посте,带上、下午的日期选择器можно посмотреть автораПроцесс пакета подключаемого модуля Vue-HalfDay-datepickerЭта статья.

Подробнее о создании компонентов см.[Серия Vue] Элегантно используйте vue для создания динамических форм (1), и здесь повторяться не будем.

Таблица конфигурации динамической формы

После завершения разработки динамического компонента будет доступна конфигурационная таблица динамической формы.

// 请假类型的map表,同后端一一对应
export const typeObj = {
    1: '年假',
    2: '病假',
    3: '调休',
    4: '事假',
    5: '婚假',
    6: '丧假',
    7: '产假',
    8: '陪产假',
    9: '补假',
}

/**
 * 所有请假表单的动态配置config
 */
export const setFormConfig = {
    // 年假
    1: [
        {
            "name": "start_time",
            "type": "halfdaydate",
            "title": "开始时间",
            "prompt_msg": "请选择",
            "val": null,
        }, 
        {
            "name": "end_time",
            "type": "halfdaydate",
            "title": "结束时间",
            "prompt_msg": "请选择",
            "val": null,
        }, 
        {
            "name": "leave_length",
            "type": "leavelength",
            "title": "请假时长",
            "prompt_msg": "请选择",
            "val": null,
        }, 
        {
            "name": "notes",
            "type": "multiple",
            "title": "请假事由(必填):",
            "prompt_msg": "请输入请假事由",
            "val": null,
        }
    ],

    // 病假
    2: [
        {
            "name": "start_time",
            "type": "halfdaydate",
            "title": "开始时间",
            "prompt_msg": "请选择",
            "val": null,
        }, 
        {
            "name": "end_time",
            "type": "halfdaydate",
            "title": "结束时间",
            "prompt_msg": "请选择",
            "val": null,
        }, 
        {
            "name": "leave_length",
            "type": "leavelength",
            "title": "请假时长",
            "prompt_msg": "请选择",
            "val": null,
        }, 
        {
            "name": "notes",
            "type": "multiple",
            "title": "请假事由(必填):",
            "prompt_msg": "请输入请假事由",
            "val": null,
        }, 
        {
            "name": "imgs",
            "type": "images",
            "title": "上传图片:",
            "prompt_msg": "请上传图片",
            "val": null,
        }
    ],

    // 调休
    3: [
        {
            "name": "start_time",
            "type": "halfdaydate",
            "title": "开始时间",
            "prompt_msg": "请选择",
            "val": null,
        }, 
        {
            "name": "end_time",
            "type": "halfdaydate",
            "title": "结束时间",
            "prompt_msg": "请选择",
            "val": null,
        }, 
        {
            "name": "leave_length",
            "type": "leavelength",
            "title": "请假时长",
            "prompt_msg": "请选择",
            "val": null,
        }, 
        {
            "name": "overtime_compensation",
            "type": "date",
            "title": "调休替代日期",
            "prompt_msg": "请选择",
            "val": null,
        }, 
        {
            "name": "notes",
            "type": "multiple",
            "title": "请假事由(必填):",
            "prompt_msg": "请输入请假事由",
            "val": null,
        }, 
        {
            "name": "imgs",
            "type": "images",
            "title": "上传图片:",
            "prompt_msg": "请上传图片",
            "val": null,
        }
    ],

    // 事假
    4: [
        {
            "name": "start_time",
            "type": "halfdaydate",
            "title": "开始时间",
            "prompt_msg": "请选择",
            "val": null,
        }, 
        {
            "name": "end_time",
            "type": "halfdaydate",
            "title": "结束时间",
            "prompt_msg": "请选择",
            "val": null,
        }, 
        {
            "name": "leave_length",
            "type": "leavelength",
            "title": "请假时长",
            "prompt_msg": "请选择",
            "val": null,
        }, 
        {
            "name": "notes",
            "type": "multiple",
            "title": "请假事由(必填):",
            "prompt_msg": "请输入请假事由",
            "val": null,
        }
    ],

    // 婚假
    5: […],
    // 丧假
    6: […]
    // 产假
    7: […],
    // 陪产假
    8: […]
]

Унифицированное управление динамическими компонентами

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

// 多行文本输入框组件
export { default as Multiple } from './multiple.vue' 

// 上传图片组件
export { default as Images } from './images.vue' 

// 日期选择器组件(整天)
export { default as Date } from './date_picker.vue' 

// 半天日期选择器组件(上/下午)
export { default as Halfdaydate } from './halfdaydate_picker/index.vue' 

// 请假时长计算器
export { default as leavelength } from './leaveLength/index.vue'

На странице динамической формы единое динамическое введение, черезcomponentРендеринг в виде динамических компонентов, я не знаю о динамических компонентах vue, нажмите здесьДинамические компоненты и асинхронные компоненты.

<template>
    <div class="g-context">
        <section class="form-wrap">
	    // …
            <component 
                v-for="(item, number) in freedomConfig" 
                :key="item.name"
                :is="item.type" 
                :item="item" 
                :preFormData="preFormData"
                :number="number"
                @changeComponent="changeComponentHandle"
            ></component>
        </section>
         // ….
    </div>
</template>

<script>
// …
import * as itemElements from '../../components/itemElement'

export default {
    // …
    props: ['type'], // type 请假类型
    components: itemElements,
}

С помощью таблицы конфигурации типов отпусков и динамических форм в сочетании с динамическими компонентами формы, необходимые для каждого типа отпусков, будут отображаться точно, а также будут следовать сводка данных формы и методы проверки.[Серия Vue] Элегантно используйте vue для создания динамических форм (1)Почти то же самое, вы можете перейти к этой статье для деталей.

из них о请假时长计算器Обработка должна динамически рассчитываться в соответствии со временем начала и временем окончания, которые подробно обсуждаются здесь. Свойства, созданные динамическими компонентами:preFormData="preFormData”,preFormDataЭто сводка данных всей формы, которая предоставляется каждому компоненту.请假时长计算器компонентwatchэто свойство.

watch: {
    preFormData: {
        handler(v, o) {
            this.throttleHandle(() => {
                const { start_time, end_time} = v

                // 公共方法计算出请假时长
                let leaveDays = leaveDaysCalculator(start_time, end_time)
                this.value = leaveDays

                this.$emit('changeComponent', {
                    number: this.number,
                    value: leaveDays
                })
            })
        },
        deep: true,
        immediate: true
    }
},

нужно обратить вниманиеwatchиспользование, это используетdeep、immediateсвойства, гдеdeep: trueозначает глубокий мониторинг,immediate: trueУказывает, что callback будет вызван сразу после начала прослушивания, штамп использования неясенИспользование часов.

резюме

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

В настоящее время в отрасли уже существуют комплексные решения, такие как решение для унифицированной формы от Alibaba.Formily(Реализация React), вы можете учиться и понимать сами, читать планы других людей и обнаруживать, что вам есть чему поучиться, давай~