如何为密码输入框设置失焦触发的验证样式
问题
我有一个包含长度、大小写字母、数字、特殊字符等验证规则的密码输入框。当前验证逻辑为:输入符合要求时验证标签变绿,未满足要求时变红。但我希望仅在用户完成输入(离开输入框)后才应用这些样式:初始状态下所有验证标签为黑色,只有用户离开输入框后,才根据输入内容切换为绿色(符合规则)或红色(不符合规则)。
原代码如下:
import React from "react"; class Password extends React.Component { constructor(props) { super(props); this.state = { text: "", req: { len: "invalid", cap: "invalid", num: "invalid", spec: "invalid" } }; } handleChange = (e) => { this.setState({ text: e.target.value }); }; render() { let reqState = {}; reqState.len = this.state.text.length >= 7 ? "valid" : "invalid"; reqState.cap = this.state.text.match(/[A-Z]/) ? "valid" : "invalid"; reqState.low = this.state.text.match(/[a-z]/) ? "valid" : "invalid"; reqState.num = this.state.text.match(/[0-9]/) ? "valid" : "invalid"; reqState.spec = this.state.text.match(/[~!@#$%^&*\-_]/) ? "valid" : "invalid"; return ( <div style={styles.login}> <input type="password" style={styles.inputs} placeholder="Password" value={this.state.text} onChange={this.handleChange} /> <h4>Password Requirements</h4> <div style={styles.reqs}> <ul style={styles.requirements}> <li style={styles[reqState.len]}>8-13 Characters</li> <li style={styles[reqState.cap]}>At least 1 Capitalcase</li> <li style={styles[reqState.low]}>At least 1 lowercase</li> <li style={styles[reqState.num]}>At least 1 number</li> <li style={styles[reqState.spec]}>At least 1 special character</li> </ul> </div> </div> ); } } export default Password;
const styles = { login: { width: "75%" }, inputs: { display: "block", margin: "0 auto", marginTop: "20px", padding: "12px", borderRadius: "0.5" }, button: { padding: "16px", marginTop: "20px", backgroundColor: "#113163", color: "#efefef", fontSize: "large" }, reqs: { margin: "0 auto", width: "60%" }, requirements: { textAlign: "left" }, valid: { color: "green" }, invalid: { color: "red" } };
解决方案
通过添加焦点状态标记,控制验证样式的触发时机,具体修改如下:
- 新增状态字段:在
state中添加isBlurred,初始值为false,标记输入框是否已失去焦点 - 添加失焦处理方法:实现
handleBlur,当输入框失去焦点时将isBlurred设为true - 修改验证样式逻辑:仅当
isBlurred为true时,才应用valid/invalid样式;否则使用默认黑色样式 - 新增默认样式:在
styles中添加normal样式,用于初始状态的黑色文本
修改后的完整代码:
import React from "react"; class Password extends React.Component { constructor(props) { super(props); this.state = { text: "", isBlurred: false // 新增:标记输入框是否已失焦 }; } handleChange = (e) => { this.setState({ text: e.target.value }); }; // 新增:处理输入框失焦事件 handleBlur = () => { this.setState({ isBlurred: true }); }; render() { let reqState = {}; // 计算验证状态 reqState.len = this.state.text.length >= 7 ? "valid" : "invalid"; reqState.cap = this.state.text.match(/[A-Z]/) ? "valid" : "invalid"; reqState.low = this.state.text.match(/[a-z]/) ? "valid" : "invalid"; reqState.num = this.state.text.match(/[0-9]/) ? "valid" : "invalid"; reqState.spec = this.state.text.match(/[~!@#$%^&*\-_]/) ? "valid" : "invalid"; return ( <div style={styles.login}> <input type="password" style={styles.inputs} placeholder="Password" value={this.state.text} onChange={this.handleChange} onBlur={this.handleBlur} // 绑定失焦事件 /> <h4>密码要求</h4> <div style={styles.reqs}> <ul style={styles.requirements}> {/* 根据isBlurred决定应用哪种样式 */} <li style={this.state.isBlurred ? styles[reqState.len] : styles.normal}>8-13个字符</li> <li style={this.state.isBlurred ? styles[reqState.cap] : styles.normal}>至少1个大写字母</li> <li style={this.state.isBlurred ? styles[reqState.low] : styles.normal}>至少1个小写字母</li> <li style={this.state.isBlurred ? styles[reqState.num] : styles.normal}>至少1个数字</li> <li style={this.state.isBlurred ? styles[reqState.spec] : styles.normal}>至少1个特殊字符</li> </ul> </div> </div> ); } } export default Password;
const styles = { login: { width: "75%" }, inputs: { display: "block", margin: "0 auto", marginTop: "20px", padding: "12px", borderRadius: "0.5" }, button: { padding: "16px", marginTop: "20px", backgroundColor: "#113163", color: "#efefef", fontSize: "large" }, reqs: { margin: "0 auto", width: "60%" }, requirements: { textAlign: "left", listStyle: "none", paddingLeft: 0 }, valid: { color: "green" }, invalid: { color: "red" }, normal: { // 新增:初始状态的黑色文本 color: "#000" } };
优化后效果

内容的提问来源于stack exchange,提问作者Katyellen
相关产品推荐
相关产品推荐

