本篇參考:
https://developer.salesforce.com/docs/component-library/bundle/lightning-input/documentation
https://www.lightningdesignsystem.com/components/input/#Error
當我們在前端有表單操作或者有大量的輸入性條件作為搜索條件情況下, 通常會有一些校驗,比如非空校驗,類型校驗等等。針對salesforce lwc也好或者是aura也好,通常有以下情況的前端校驗。
- badInput:用來判斷當前的輸入內容是否是一個合法的值;
- patternMismatch:用來判斷當前輸入內容是否符合指定模式;
- rangeOverflow:針對數字相關的類型判斷輸入內容是否值過大超過了默認的最大值;
- rangeUnderflow:針對數字相關的類型判斷輸入內容是否值過小小於默認的最小值;
- stepMismatch:針對數字相關的類型,我們在輸入框使用上或者下按鈕以后,可以根據step設置的值進行相關的輸入框內容的加或者減,當我們自己改的最終的值不符合step設定,會報錯stepMismatch;
- tooLong:指定value的長度是否超過當前設定的maxlength;
- tooShort:指定value的長度是否小於當前設定的minlength;
- typeMismatch:針對url或者email類型的變量,用來判斷當前輸入的value類型是否匹配;
- valueMissing:針對必填字段沒有填值情況下會報錯這種類型錯誤。
當表單中校驗出現這種情況時,會展示相關的默認的錯誤提示信息。
badInput
: Enter a valid value.patternMismatch
: Your entry does not match the allowed pattern.rangeOverflow
: The number is too high.rangeUnderflow
: The number is too low.stepMismatch
: Your entry isn't a valid increment.tooLong
: Your entry is too long.tooShort
: Your entry is too short.typeMismatch
: You have entered an invalid format.valueMissing
: Complete this field.
下圖我們恐怕很熟悉了,經常看到類似當輸入框不滿足情況的默認的展示信息。通過下圖可以更好的了解上面的一部分信息。
上面截圖中的標紅的效果展示即為本篇講的validity,validity的使用可以使用戶在大量的入力操作部分不滿足情況下可以進行更好的定位,達到更好的用戶體驗。
標紅操作的css實現樣式可以查看上方的參考鏈接。我們本篇考慮的更多是如何使用。
在form表單中的入力選擇的標簽大部分都內置了checkValidity / reportValidity / setCustomValidity或者類似函數。比如 input / combobox等等標簽。checkValidity用於驗證當前的表單的元素是否符合要求,reportValidity用於在checkValidity基礎上進行效果展示。如果當前元素符合要求,錯誤信息清除並且return true;如果當前元素不符合要求,則展示錯誤信息並且return false。
let allValid = [...this.template.querySelectorAll('lightning-input')] .reduce((validSoFar, inputFields) => { inputFields.reportValidity(); return validSoFar && inputFields.checkValidity(); }, true);
我們對上面的代碼進行分析:
- 通過querySelectorAll獲取到當前組件中 lightning-input;
- 對每一個 lightning-input元素使用reportValidity方法進行校驗,如果當前元素符合要求,則返回true,如果不符合要求,返回false並且元素根據錯誤的類型展示錯誤的默認信息;
- 通過checkValidity來確認當前元素是否符合,符合返回true,不符合返回false。
需要注意的是,當form表單提交的時候,如果頁面中有不符合的元素,並不會阻斷你的表單提交。所以我們在頁面提交以前如果看到了上面類似的提示不要掉以輕心,需要在save以前進行check,成功走save邏輯,不成功需要返回並且reportValidity()。
通過上面的demo中,我們可以看到使用querySelectorAll來遍歷所有lightning-input元素進行reportValidity和checkValidity,這種方式只能遍歷到當前component中的所有元素。如果組件包含了子組件,子組件中包含了 input等類似元素,並不能對子組件中的進行校驗。以一個demo進行試驗。
testSonInputComponent.html:僅用於展示一個輸入框
<template> <lightning-input label="test son" required></lightning-input> </template>
testParentInputComponent.html:引入testSonInputComponent並且在放一個input組件
<template> <lightning-layout multiple-rows="true"> <lightning-layout-item size="6"> <lightning-input label="test parent" type="text" required></lightning-input><br/> </lightning-layout-item> <lightning-layout-item size="6"> <c-test-son-input-component></c-test-son-input-component> </lightning-layout-item> <lightning-layout-item> <lightning-button label="validity" onclick={checkInputValidity}></lightning-button> </lightning-layout-item> </lightning-layout> </template>
testParentInputComponent.js:遍歷所有的input標簽,進行reportValidity操作。
import { LightningElement } from 'lwc'; export default class TestParentInputComponent extends LightningElement { checkInputValidity() { let allValid = [...this.template.querySelectorAll('lightning-input')] .reduce((validSoFar, inputFields) => { inputFields.reportValidity(); return validSoFar && inputFields.checkValidity(); }, true); console.log('result : ' + allValid); } }
效果展示:當標簽都沒有輸入情況下,只會校驗到當前組件中的標簽,子組件標簽不會被校驗到。
如果想要校驗到,目前想到的方法為父組件調用子組件的方法,可以將相關子組件的校驗功能彌補,但是無法將checkValidity的結果傳遞過來。如果想要查看allValid,只能在父組件根據是否有值,然后手動設置allValid變量。代碼簡單修改如下:
testInputSonComponent.js:對方法進行api標簽聲明,只有聲明以后父組件才可以調用。
import { LightningElement, api } from 'lwc'; export default class TestSonInputComponent extends LightningElement { @api checkInputValidity() { let allValid = [...this.template.querySelectorAll('lightning-input')] .reduce((validSoFar, inputFields) => { inputFields.reportValidity(); return validSoFar && inputFields.checkValidity(); }, true); } }
testInputParentComponent.js:通過querySelector獲取到子組件,然后調用子組件方法即可。
import { LightningElement } from 'lwc'; export default class TestParentInputComponent extends LightningElement { checkInputValidity() { let allValid = [...this.template.querySelectorAll('lightning-input')] .reduce((validSoFar, inputFields) => { inputFields.reportValidity(); return validSoFar && inputFields.checkValidity(); }, true); this.template.querySelector('c-test-son-input-component').checkInputValidity(); console.log('result : ' + allValid); } }
效果展示:
此種方式的一個最大的問題是子組件的validity的結果並無法傳遞給父組件。項目中是根據子組件的值是否為空在父組件中校驗然后設置allValid的值,除此以外沒有想到好的方法,熟悉的小伙伴可以給出更好的方案。
除了標准的提示信息以外,lwc給我們提供了一個自定義error message的方法,即setCustomValidity。此方法在很多方法中均有類似的方法,用於當標准的提示信息不滿足需求的時候或者自定義的一些校驗想要展示自定義的提示信息情況下,使用的方案。當使用setCustomValidity,結合reportValidity即可展示自定義的error場景提示了。
對代碼繼續改造。當輸入框內容不到2個字符進行自定義提示。
import { LightningElement } from 'lwc'; export default class TestParentInputComponent extends LightningElement { checkInputValidity() { let allValid = [...this.template.querySelectorAll('lightning-input')] .reduce((validSoFar, inputFields) => { if(inputFields.value.length < 2) { console.log('execute'); inputFields.setCustomValidity('輸入的長度應該超過2'); } inputFields.reportValidity(); return validSoFar && inputFields.checkValidity(); }, true); this.template.querySelector('c-test-son-input-component').checkInputValidity(); console.log('result : ' + allValid); } }
結果展示:
總結:篇中簡單的介紹了Validity的簡單實用,針對子組件如何更好的適應還沒有特別好的方案,有好想法的朋友留言。篇中有不懂的歡迎留言,有錯誤的歡迎指出。