歷史回顧:javascript
工做臺模塊,新需求要作請假審批,開需求評審的時候,瞭解到請假有:年假 、病假、調休、事假 、婚嫁、喪假期、產假、陪產假等8種類型。筆者第一個想法就是不想寫多個表單頁面,也不想在一個表單頁面中寫不少的判斷類型邏輯。因而就試探性詢問可否由後端配合作動態表單,畢竟以前作一次。可是後端和產品都一致認爲此次表單的變動不大,不必再開發一個表單的配置系統。不開心吶,需求評審完成以後筆者開始調研實現方案和技術選型。html
思考着可否由前端全權動態表單操控處理?這樣就能夠減輕後端的開發時長和壓力,固然此次需求就比較重前端了。那就來個動態表單,根據不一樣的請假類型,自動生成表單,雖然在首次開發須要更多的思考和設計,可是後期方便維護啊。筆者也是對需求、對業務、對代碼有要求的人。哼~前端
那麼問題來了,若是採用動態表單的話,小程序並無動態組件能夠方便處理,因而筆者考慮選用小程序內嵌h5的方式,h5採用vue框架。技術方案和技術選型就肯定好了。vue
針對8種請假類型:年假 、病假、調休、事假 、婚嫁、喪假期、產假、陪產假的表單,提煉出須要用到的組件,以及須要生成動態表單的配置表。java
這份組件圖,主要給咱們的內部開發人員看,一目瞭然地知道怎麼去作代碼的組織和構建。下面總結了動態表單由哪些組件組成,各個組件之間的關係和依賴,以及組件依賴的三方和框架。算法
總結須要開發的組件有:vue-router
其中 請假時長計算器
在筆者的造輪子 | 如何開發一個請假時長計算器?這篇文章中查看實現細節和詳情,帶上、下午的日期選擇器
能夠查看筆者vue-halfday-datepicker插件的封裝過程這篇文章。vuex
建立組件的細節請參考【vue系列】優雅地用 vue 生成動態表單(一),這裏就再也不贅述了。npm
動態組件開發完成,動態表單的配置表就能出來了。element-ui
// 請假類型的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 生成動態表單(一)幾乎同樣,能夠去這篇查看細節處理。
其中關於 請假時長計算器
的處理,須要根據,開始時間和結束時間動態計算,這裏再具體說說。 動態組件生成的屬性 :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
表明該回調將會在偵聽開始以後被當即調用, 還不清楚用法的戳 watch的用法。
筆者的處理方法不必定是最優的,或者能夠採用雙向數據綁定的方案。整體上來講,我想作的事情想把如何建立動態表單的思路,以及設計方案表述出來作個記錄,也不知道講清楚了沒有🤦♀️。若是你有好思路或者疑惑,歡迎在評論區留言與我討論。業界目前已經有很完善的解決方案,好比阿里的 [Formily](https://formilyjs.org/#/bdCRC5/dzUZU8il)
,你們能夠自行學習瞭解,看了別人方案,發現本身還有更多須要學習的地方,加油~