Summer '18发布后Salesforce Lightning Input的element.set失效问题
解决Summer '18后Lightning Input手机号格式化失效及允许字母输入的问题
我来帮你搞定这个问题——Summer '18发布后Salesforce调整了Lightning组件的输入处理逻辑,这直接导致了你遇到的两个核心问题:无法通过element.set设置格式化后的值,以及输入框能接受非数字字符。下面我一步步给你拆解原因和修复方案:
问题根源分析
- 无法设置格式化值:Summer '18之后,
lightning:input的onchange事件触发时,组件内部已经启动了双向绑定的value更新流程,你在事件处理中直接调用element.set('v.value')会被组件的默认行为覆盖,导致设置失效。 - 允许字母输入:你用的是
type="text"类型的输入框,本身就不限制输入内容,加上原来的校验是在输入完成后才处理,没法实时阻止非法字符输入。
修复方案及代码修改
1. 调整Lightning Input组件配置
首先把输入框类型改成tel(专门用于电话输入,移动端会自动弹出数字键盘),同时加上pattern属性限制输入格式,还可以开启原生的错误提示:
<aura:application extends="force:slds"> <lightning:input type="tel" label="Num" aura:id="ele" onchange="{!c.changeNum}" pattern="[0-9\-]*" showHelpMessageWhenInvalid="true" messageWhenPatternMismatch="请输入有效的手机号格式" /> </aura:application>
2. 修改Helper逻辑,阻止默认更新并正确设置值
在onchange事件中先调用event.preventDefault()阻止组件的默认value更新,然后再设置格式化后的值,同时优化手机号格式化逻辑:
// Controller保持原代码即可 ({ changeNum : function(component, event, helper) { helper.changeNum(component, event); } })
({ changeNum : function(component, event) { // 先阻止组件默认的value更新,避免覆盖我们的格式化值 event.preventDefault(); var element = event.getSource(); var phonenumber = element.get("v.value"); if(phonenumber){ // 先移除所有非数字字符 var cleanedValue = phonenumber.replace(/[^0-9]/g, ""); // 格式化手机号为XXX-XXX-XXXX格式(可根据需求调整正则) if(cleanedValue.length > 0){ var formattedValue = cleanedValue.match(/(\d{0,3})(\d{0,3})(\d{0,4})/).slice(1).join("-").replace(/-$/, ""); phonenumber = formattedValue; } } console.log(phonenumber); // 现在设置值就不会被组件默认行为覆盖了 element.set('v.value', phonenumber); } })
3. 额外优化:实时阻止非法输入(可选)
如果想要在用户输入时就阻止非数字和非横杠字符,可以添加onkeypress事件:
<!-- 更新lightning:input,添加onkeypress事件 --> <lightning:input type="tel" label="Num" aura:id="ele" onchange="{!c.changeNum}" onkeypress="{!c.validateKey}" pattern="[0-9\-]*" showHelpMessageWhenInvalid="true" messageWhenPatternMismatch="请输入有效的手机号格式" />
然后在Controller中添加validateKey方法:
({ changeNum : function(component, event, helper) { helper.changeNum(component, event); }, validateKey : function(component, event) { var key = event.key; // 只允许数字和横杠输入 if(!/[0-9\-]/.test(key)){ event.preventDefault(); } } })
为什么这样修改有效?
event.preventDefault():打断了Summer '18后组件内部的双向绑定更新流程,让我们的格式化值能成功设置到组件上。type="tel"和pattern:从组件层面限制输入类型,配合原生错误提示,提升用户体验。- 实时按键校验:提前阻止非法字符输入,减少后续格式化的复杂度。
内容的提问来源于stack exchange,提问作者Ashutosh Jha
相关产品推荐
相关产品推荐

