asp.net接受表单验证格式后再提交数据_看滴普科技大前端如何玩转el-form-renderer 表单渲染器1.14.0
DEEPEXI 大前端
常人道,一入開發深似海,技術學習無止境。在新技術層出不窮的前端開發領域,有一群身懷絕技的開發,他們在鉆研前沿技術的同時,也不忘分享他們的成果,回饋社區。下面,就由小水滴帶大家看一下滴普大前端對新版 el-form-renderer 表單渲染器的硬核解析吧~
DEEPEXI是滴普科技公司面向企業數字化領域打造的云原生智能平臺,定位于企業數字化引擎,為企業提供數字化全棧解決方案。滴普科技致力于互聯網/大數據/人工智能/物聯網領先技術產品解決方案的研發和實施,是領先的企業數字化建設者。
el-form-renderer與表單
表單面臨的難題
表單本質上是什么?表單用來承載業務需求的交互邏輯,表單的最終目的是提交一些特定格式的數據。
但在日常工作中,公司的業務不會停下,需求必然要跟著業務而不斷演化,一個看似簡單的頁面表單也會變得越來越臃腫。
表單變得難以維護
拿項目交接舉例子。項目交接了N手,各人都按各自的風格寫代碼;產品也交接了好幾手,各按各的套路提需求。根本原因是代碼的維護成本與業務不斷變化之間的矛盾。當表單中出現聯動的需求,或者跨行之間發生制約關系時,表單代碼的復雜度就會上升。隨著業務需求的演變,如果代碼處理的不好,會變得越來越難維護。
為什么要用el-form-renderer
el-form-renderer是基于 element-ui 封裝的表單渲染器,但不局限于 element-ui 組件。在完整繼承了 element 的form表單屬性的基礎上進行了簡單擴展,一些非表單組件或者封裝的自定義組件,如圖片上傳、富文本等也可進行整合,從而用戶能夠通過使用一段預設的數據渲染出一個完整的表單。
用一句話來概括,el-form-renderer 讓表單的構建與維護變得更簡單了。
el-form-renderer(表單渲染組件)
issues
el-form-renderer 1.14.0 重磅發布
el-form-renderer 1.14.0 : 支持 v-model
版本更新主要帶來了 v-model 功能,并加入了 cypress 做 e2e 測試來護航。下面一起來看看開發小哥此時版本迭代的心路歷程吧~
功能:v-model
這次 feature 版本更新,主要是為了 v-model 功能開展的。其可以解決以下問題:
- 不再需要對 ref 操作 updateForm、getFormValue 來與數據交互。
- 可以直接觀察當前的表單數據變更,來進行特定操作。
后續對 valid 狀態,也通過 prop + sync 的形式管理,基本就可以脫離對 ref 的依賴。
提升代碼質量
由于 el-form-renderer 已經是歷時兩年多的開源項目,許多代碼經多人轉手,已經存在以下問題:
- 不合適的寫法。比如大量使用 render 函數;
- 大量使用 mixin 和字符串拼接來調用功能,開發者難以定位調用鏈條。比如在生成 option 數組時;
- 廢棄的功能。比如不太好用的 enableWhen 等等;
- 沒有注釋的 hack。比如嘗試兼容 select, radio & checkbox 用法的代碼(在1.14.1版本修復)。
所以提高維護性也是本次迭代的重中之重。開發從此開始。
測試
第一步,加入自動化測試。先前,項目中已經引入了 jest 做單元測試。單元測試可以保證一些核心邏輯的穩定性,比如一些數據處理、轉換函數的輸入輸出意圖。但是其沒有辦法測試真實示例使用起來時的穩定性,比如用戶真正在表單中輸入值、點擊重置按鈕的行為。
此前,行為的穩定性只能依賴開發者和 review 人員手動對示例進行測試。現在,項目使用 cypress 來對每個示例的行為進行自動化測試。這樣開發者可以放心重構和添加功能,同時輕松維護過往表現的一致性。
如何寫行為測試
重點應當關注用戶行為層面,而不是代碼輸出層面。
比如,應當測試:
- 用戶輸入文本。
- 確認文本框中有該內容。
- 用戶點擊提交按鈕。
- 確認窗口內顯示成功信息。
而不是:
- 用戶點擊按鈕。
- 等待某個接口有返回內容(測試按鈕有沒綁定到函數,和接口是否正常)。
重構
重構的主要成果是:
- 用 template 重構了所以 render 函數。代碼更符合 vue 規范寫法。
- 移除了 mixin。將相關功能轉化成純函數,并補充單元測試用例。
- 層級調整。vue 組件移到 components 目錄下;js 文件移到 util 目錄下。
- 優化函數命名。比如使用具體的 removeDollarInKey 替代 transformItem。
- 梳理了關鍵復雜點的邏輯,并提取成純函數,補充單元測試。
- 補全了所有關鍵示例的端測試。
其中補充的單元測試包括:transformInputFormat(用 inputFormat 處理初始和 updateForm 的值);transformOutputFormat (用 outputFormat 處理 getFormValue 的值);collect (從 content 中搜集 options 和初始 value。
inputFormat & outputFormat
這次重構的最大難點,就是處理 inputFormat、 outputFormat、group 與表單值 value 的邏輯。直接給出定義的話:
- 每個表單項的 inputFormat 接受當前 這一層(group) 的值,返回 當前項的值。
- 每個表單項的 outputFormat 接受 當前項的值 ,返回的值先判斷是不是對象:
- 如果不是,返回值視作 當前項的值。
- 如果是,返回值將整體覆蓋到 這一層(group) 的值。
 
具體看如下示例。使用到的同學請務必注意其用法。
inputFormat
重構前:
/ content 配置{id: 'a',inputFormat: v => v + 1 // 接受傳入值,返回新值}//this.$refs.form.updateForm({a: 1})this.$refs.form.getFormValue() // {a: 2}重構后:
// content 配置{id: 'a',inputFormat: formValue => formValue.notA // 接受整個 formValue 來處理!}//this.$refs.form.updateForm({notA: 1})this.$refs.form.getFormValue() // {a: 1}outputFormat
重構前:
// content 配置[{id: 'a',default: 1,outputFormat: a => a + 1 // 接受內部值,返回處理過的值},{id: 'b',default: {c: 2},outputFormat: b => (b.c += 1, b)},]//this.$refs.form.getFormValue() // {a: 2, b: {c: 3}}重構后:
// content 配置[{id: 'a',default: 1,outputFormat: a => a + 1 // 這個的理解是對的},{id: 'b',default: {c: 2},outputFormat: b => (b.c += 1, b) // 當返回值是對象時,會整體覆蓋到上一層!},]//this.$refs.form.getFormValue() // {a: 2, c: 3}開發功能:v-model
開發過程
- 新增屬性 form,作為對外 v-model 的屬性。
- 在 watch 里對接數據流水線:
- 監聽 form、content 的變更 -> 搜集初始值 --inputFormat--> value
- 監聽 value 的變更 --outputFormat--> form
- 寫新的示例 v-model.md 和測試 v-model.spec.js(參考 basic 即可)。
測試流程
- 輸入各種 input、select、radio。
- 檢查輸入后 v-model 的狀態。
- 點擊 reset 按鈕,v-model 回到初始狀態。
發現問題
- 在模擬點擊 reset 按鈕時,當 cypress 測試里點擊重置按鈕, reset 未生效。
- 手動在 cypress 的調試瀏覽器中點擊按鈕,reset 生效。
- 在普通瀏覽器中點擊按鈕,reset 生效 。
- 在 reset 函數里打點,此時 reset 函數在以上情況中 都有被正常調用。
- 嘗試在 cypress 代碼中先等待1秒再點擊按鈕,reset 未生效。
- 嘗試在 cypress 代碼中連續寫兩次 click 按鈕操作,reset 生效。
發現有可能是 cypress 的問題,標明注釋說明手動測試成功,連點兩次是 hack 寫法。
解決問題
review 了下原本的 resetFields 邏輯,發現了如下問題:
- reset 后 el-select 報錯的 bug。
- reset 后,value 監聽器監聽不到改變,因為 el-form 的實現機制中改了 value 后沒有 emit input 事件。
- 如果在監聽器上加 deep: true,則會發現新值和舊值相同。原因暫時不明。
在發現以上問題基礎上,對代碼進行如下修改:
- 在 form、value 監聽器中用 lodash 的 isequal 判斷前后的值,有變更時才 emit input 事件。
- 參考 el-form 機制在內部實現了 resetFields:用的是 mounted 時傳入的值,然后清除校驗錯誤信息。
解決了用例異常的問題,有如下總結:
- 仍沒有弄清楚為什么 cypress 的模擬操作代碼調用的 resetFields 沒有正常運作。
- 疑似 cypress 的問題導致 resetFields 的其他問題被發現。
- 重視測試的心以一種特別的方式讓組件得到了回報。
關于初始狀態
值得一提的是,目前 resetFields 所認定的 初始狀態,是在組件 mounted 階段時 v-model 的值。這點與 element 一致,因為一些 element 表單組件,會在 created 階段,在傳入的 value 值不合法時會重新 emit 一個正確的初始值給到 v-model。比如:
- 開啟了 multiple 的 el-select,會修正初始值為 [] 。
- el-checkbox,會修正初始值為 [] (由 el-form-renderer 實現,原生是沒有的)。
更新文檔
此次更新順帶修復了一些老示例的錯誤用法。可能不少 el-form-renderer 的用戶還不了解,el-form-renderer 的 disabled 屬性,統一在配置最上層級設置:
// content 定義[{disabled: true, // 在這里設置el: {disabled: true // 無效}}]在寫 v-model 數據流水線時,因為把 content 也融入在其中,所以現在可以在運行時修改 content,并觀測表單變化。
結語
el-form-renderer 雖然一路遭遇到吐槽很多,但更多的是忠實粉絲們孜孜不倦地為其提交代碼。直到今天,可以看到其相對于原生 element,開發體驗已經有了長足的進步。現在有了端對端測試,開發和維護功能更是如虎添翼。這里感謝已為開源作出貢獻的開發者們,也歡迎更多小伙伴加入我們 DEEPEXI 開源生態中哦~
“作家不靠靈感寫字??”
作者:沈揚東
更多內容請點擊左下方“了解更多”
總結
以上是生活随笔為你收集整理的asp.net接受表单验证格式后再提交数据_看滴普科技大前端如何玩转el-form-renderer 表单渲染器1.14.0的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 加密解密php,2个比较经典的PHP加密
- 下一篇: java cache详解,Java内存缓
