React + TS 封装密码强度组件

Posted HappyCodingTop

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React + TS 封装密码强度组件相关的知识,希望对你有一定的参考价值。

在antd的Progress的基础上封装
PwdStrength.tsx

import { Col, Progress, Row } from \'antd\';
import { FC } from \'react\';
import styles from \'./index.less\';
interface IPwdStrengthProps {
  pwdStrength: 0 | 1 | 2 | 3;
}
const PwdStrength: FC<IPwdStrengthProps> = ({ pwdStrength }) => {
  return (
    <div className={styles.passwordStrongBox}>
      <Row gutter={12}>
        <span className={styles.passWord}>密码强度</span>
        <Col span={3}>
          <Progress className={styles.weak} percent={pwdStrength > 0 ? 100 : 0} showInfo={false} />
        </Col>
        <Col span={3}>
          <Progress className={styles.middle} percent={pwdStrength > 1 ? 100 : 0} showInfo={false} />
        </Col>
        <Col span={3}>
          <Progress className={styles.strong} percent={pwdStrength > 2 ? 100 : 0} showInfo={false} />
        </Col>
        <span className="passStrong">
          {pwdStrength === 1 && \'弱\'}
          {pwdStrength === 2 && \'中\'}
          {pwdStrength === 3 && \'强\'}
        </span>
      </Row>
    </div>
  );
};
export default PwdStrength;

覆盖原有样式,根据强度各个进度显式不同颜色,样式献上
index.less

.passwordStrongBox {
  margin-top: 4px;
  .weak {
    :global .ant-progress-bg {
      background-color: #f50 !important;
    }
  }

  .middle {
    :global .ant-progress-bg {
      background-color: #e4ce2b !important;
    }
  }

  .strong {
    :global .ant-progress-bg {
      background-color: #87d068 !important;
    }
  }

  .passWord {
    display: inline-block;
    margin: 3px 8px 0 6px;
    color: rgba(140, 140, 140, 100);
    font-size: 12px;
  }
  .passStrong {
    display: inline-block;
    margin: 3px 0 0 8px;
    color: rgba(89, 89, 89, 100);
    font-size: 11px;
  }
}

利用正则判断用户输入的密码的强度
useChangePassword.ts

const pattern_1 = /^.*([0-9])+.*$/i; //数字
const pattern_2 = /[a-z]/; //小写字母
const pattern_3 = /[A-Z]/; //大写字母
const pattern_4 = /[`~!@#$%^&*()\\-_+=\\\\|{}\':;\\",\\[\\].<>\\/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]/; //特殊字符
export function useChangePassword() {
  const getPwdStrength = (pwd: string): 0 | 1 | 2 | 3 => {
    let level = 0;
    if (pwd) {
      pwd = pwd.trim();
      if (pwd.length >= 6) {
        if (pattern_1.test(pwd)) {
          level++;
        }
        if (pwd.length > 10) {
          level++;
        }
        if (pattern_2.test(pwd) || pattern_3.test(pwd)) {
          level++;
        }
        if (pattern_4.test(pwd)) {
          level++;
        }
        if (level > 3) {
          level = 3;
        }
      }
    }

    return level as 0 | 1 | 2 | 3;
  };
  return {
    getPwdStrength,
  };
}

数据管理
store.ts

import { reduxStore } from \'@/createStore\';
export const store = reduxStore.defineLeaf({
  namespace: \'personal\',
  initialState: {
    pwdStrength: 0 as 0 | 1 | 2 | 3,
  },
  reducers: {
    changePwdStrength(state, payload: 0 | 1 | 2 | 3) {
      state.pwdStrength = payload;
    },
  },
});

使用

import { store } from \'../../store\';
import PwdStrength from \'../PwdStrength\';
 const { pwdStrength } = store.useState();
const { getPwdStrength } = useChangePassword();


  <ProFormText.Password
            placeholder="新密码"
            rules={[
              {
                required: true,
                message: \'请输入新密码\',
              },
            ]}
            
            name="newPassword"
            label="新密码"
            help={<PwdStrength pwdStrength={pwdStrength} />}
            fieldProps={{ onChange: (e) => store.changePwdStrength(getPwdStrength(e.target.value)) }}
          />

判断密码逻辑

 handleSubmit = (e: any) => {
    e.preventDefault();
    this.props.form.validateFields((err: Error, values: any) => {
      if (!err) {
        const { oldPwd, newPwd } = values;

        QMFetch({
          host: \'v_app_api\',
          url: \'api/store/account/modify/password\',
          method: \'POST\',
          body: {
            oldPassword: oldPwd,
            newPassword: newPwd,
          },
        })
          .then((data: any) => {
            const res = data.data;
            if (typeof res.success === \'boolean\' && res.success === true) {
              this.props.close();
              this.timer();
              Modal.success({
                title: \'修改成功!\',
                content: \'3秒后将退出到登录页面\',
                okText: \'确定\',
                onOk: () => {
                  const url = QMConst.HOST[\'v_sso_server\'] + \'/logout?r=changepwd&all=modifyPwd\';
                  location.href = url;
                },
              });
            } else {
              message.error(res.message);
            }
          })
          .catch((err: Error) => message.warning(err.message));
      }
    });
  };

  pwdStrength = (pwd: string) => {
    const pattern_1 = /^.*([0-9])+.*$/i; //数字
    const pattern_2 = /[a-z]/; //小写字母
    const pattern_3 = /[A-Z]/; //大写字母
    const pattern_4 = /[`~!@#$%^&*()\\-_+=\\\\|{}\':;\\",\\[\\].<>\\/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]/; //特殊字符
    let level = 0;
    pwd = pwd.trim();
    if (pwd.length >= 6) {
      if (pattern_1.test(pwd)) {
        level++;
      }
      if (pwd.length > 10) {
        level++;
      }
      if (pattern_2.test(pwd) || pattern_3.test(pwd)) {
        level++;
      }
      if (pattern_4.test(pwd)) {
        level++;
      }
      if (level > 3) {
        level = 3;
      }
    }
    return level;
  };

  newPwdChange = (e: any) => {
    const newPwd = e.target.value;
    // 计算密码强度
    this.setState({
      level: this.pwdStrength(newPwd),
    });
  };

  checkNewPwd = (rule: any, value: any, callback: any) => {
    const form = this.props.form;
    value = typeof value == \'undefined\' ? \'\' : value.trim();
    if (value.length > 5 && value.length < 20) {
      if (value === form.getFieldValue(\'oldPwd\')) {
        callback(\'新密码不能和老密码相同\');
      }
      const confirmPwd = form.getFieldValue(\'confirmPwd\');
      if (confirmPwd && confirmPwd !== \'\' && confirmPwd !== value) {
        callback(\'确认密码与新密码不一致\');
      } else {
        callback();
      }
    } else {
      callback(\'新密码长度保持在6-20个字符之间\');
    }
  };

  checkOldPwd = (rule: any, value: any, callback: any) => {
    value = typeof value == \'undefined\' ? \'\' : value.trim();
    if (value.length < 6) {
      callback(\'原密码至少包含6个字符\');
    } else {
      callback();
    }
  };

  checkPassword = (rule: any, value: any, callback: any) => {
    const form = this.props.form;
    value = typeof value == \'undefined\' ? \'\' : value.trim();
    if (value !== form.getFieldValue(\'newPwd\')) {
      callback(\'确认密码与新密码不一致\');
    } else {
      callback();
    }
  };

  timer = () => {
    let i = 3;
    const time = window.setInterval(() => {
      if (i === 0) {
        const url = QMConst.HOST[\'v_sso_server\'] + \'/logout\';
        location.href = url;
        clearInterval(time);
      } else {
        i--;
      }
    }, 1000);
  };

以上是关于React + TS 封装密码强度组件的主要内容,如果未能解决你的问题,请参考以下文章

已解决在react+ts中 atnd 用 upload 组件报错Failed to execute ‘readAsArrayBuffer,param 1 is notof type Blob(代码片段

已解决在react+ts中 atnd 用 upload 组件报错Failed to execute ‘readAsArrayBuffer,param 1 is notof type Blob(代码片段

react+ts+hook封装一个table分页组件(建议收藏,直接使用)

Reactreact概述组件事件

React+hook+ts+ant design封装一个input和select搜索的组件

二次封装antd-mobile组件库