首先本篇感謝長源edward老哥的大力幫助。
背景:我們在前端開發的時候,經常會用到輸入框,並且對這個輸入框設定 required或者其他的驗證,當不滿足條件時使用自定義的UI或者使用標準的 input的 setCustomValidity等操作方式去進行UI的展示。我們在https://www.cnblogs.com/zero-zyq/p/12734982.html有描述相關的操作,今天的內容就以這個知識點內容進行展開。首先先上程式碼
inputRequiredTest.html
<template> <lightning-card title="input demo"> <lightning-input type="text" value={inputValue} onchange={handleChangeEvent} required label="test input"> </lightning-input> </lightning-card> </template>
inputRequiredTest.js
import { LightningElement, track } from 'lwc'; export default class InputRequiredTest extends LightningElement { @track inputValue = ''; handleChangeEvent(event) { this.inputValue = event.detail.value; } }
展示效果:
1. 輸入框移入再移出,因為專案有必填欄位的要求,所以會展示讓你完成這個欄位的填寫
2. 輸入內容,焦點還在輸入框中情況下,仍然展示要求必填的資訊
3. 從輸入框中移出焦點,紅色標記自動消失
有一些客戶很挑剔,希望的是當輸入內容以後就要將紅色標記移出,因為當前的輸入框已經是有值的狀態,當然這個很好實現,salesforce lwc給我們提供了 setCustomValidity方法,設定內容為空,再一report即可。優化後的 inputRequiredTest.js
import { LightningElement, track } from 'lwc'; export default class InputRequiredTest extends LightningElement { @track inputValue = ''; handleChangeEvent(event) { this.inputValue = event.detail.value; if(this.template.querySelector('lightning-input').checkValidity()) { this.template.querySelector('lightning-input').setCustomValidity(''); this.template.querySelector('lightning-input').reportValidity(); } } }
展示效果:最開始的時候是紅色的不截圖了,當輸入框裡面輸入了內容還在焦點狀態下,也不在展示紅框
此種需求便可以完美的解決。除了此種需求,有時候還會有其他類似的需求,比如當前儘管是輸入框,但是有很多模板內容供選擇,點選某個按鈕或者選擇某個單選框可以將內容給到輸入框中。將前後端程式碼修改以後的效果如下:
inputRequiredTest.html
<template> <lightning-card title="input demo"> <lightning-input type="text" value={inputValue} onchange={handleChangeEvent} required label="test input"> </lightning-input><br/> <lightning-button label="set value" onclick={handleSetValueClick}></lightning-button> </lightning-card> </template>
inputRequiredTest.js
import { LightningElement, track } from 'lwc'; export default class InputRequiredTest extends LightningElement { @track inputValue = ''; handleChangeEvent(event) { this.inputValue = event.detail.value; if(this.template.querySelector('lightning-input').checkValidity()) { this.template.querySelector('lightning-input').setCustomValidity(''); this.template.querySelector('lightning-input').reportValidity(); } } handleSetValueClick(event) { this.inputValue = 'test'; if(this.template.querySelector('lightning-input').checkValidity()) { this.template.querySelector('lightning-input').setCustomValidity(''); this.template.querySelector('lightning-input').reportValidity(); } } }
展示效果:當我們先輸入焦點,移出展示紅框以後,點選按鈕,值設定上了,竟然沒有消失???當然,此時我們將焦點消失,還是可以紅框消失。一樣的程式碼,不一樣的效果。
問了一圈無果以後私聊了牛逼的Edward老哥,根據程式碼一點點分析,是否設定 track了啊等等一圈圈排查以後,老哥說,要麼你先試試 checkValidity等幾句使用 setTimeout,等他一秒,保證 這個值順利賦值完,renderedCallback走完了,那這幾句才能有效。趕緊去試試,於是後面的程式碼變成了下面這樣。
handleSetValueClick(event) { this.inputValue = 'test'; window.clearTimeout(this.delayTimeout); this.delayTimeout = setTimeout(() => { if(this.template.querySelector('lightning-input').checkValidity()) { this.template.querySelector('lightning-input').setCustomValidity(''); this.template.querySelector('lightning-input').reportValidity(); } }, 1000); }
通過上述程式碼,當賦值以後,神奇的搞定了。按照老哥的說法,賦值以後確實改變了,可能還沒有渲染好,呼叫了後面,導致了這種尷尬的問題。
總結:篇中介紹了針對下面的這種方式如何使用 setTimeout搞定,很慚愧的是以前部落格中寫過 setTimeout的用法,但是這裡卻並想不到這個原因,學無止境,自己還需要更努力啊。篇中有錯誤地方歡迎指出,有不懂歡迎留言。有其他實現方式不吝賜教。