最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

react如何實(shí)現(xiàn)一個(gè)密碼強(qiáng)度檢測(cè)器詳解

 更新時(shí)間:2021年06月30日 09:07:56   作者:正經(jīng)修行人  
這篇文章主要給大家介紹了關(guān)于react如何實(shí)現(xiàn)一個(gè)密碼強(qiáng)度檢測(cè)器的相關(guān)資料,使用這個(gè)密碼強(qiáng)度器后可以幫助大家提高在線帳號(hào)、個(gè)人信息的安全性,需要的朋友可以參考下

前言

密碼強(qiáng)度文件校驗(yàn)器; 注冊(cè)帳號(hào)的時(shí)候我們需要對(duì)用戶當(dāng)前的密碼強(qiáng)度進(jìn)行一個(gè)評(píng)估,這個(gè)過(guò)程我們需要做一個(gè)檢測(cè)器,最好寫(xiě)的靈活點(diǎn),這樣方便產(chǎn)品修改規(guī)則。

先看下效果吧~~   下面是截圖對(duì)應(yīng)的狀態(tài)

使用

1 參數(shù)傳遞

const PasswordForce = passwordForce({     inputValue,     className: 'password-force',   });

2 使用

<PasswordForce.View />

3 校驗(yàn)

檢測(cè)是否超出字符PasswordForce.invaildWord

實(shí)現(xiàn)例子

我們配置antd實(shí)現(xiàn)下密碼輸入框上面綁定一個(gè)提示器吧

1,2都是不需要改的,但是實(shí)際我們需要監(jiān)聽(tīng)input的值然后設(shè)置值。于是我們可以定義一個(gè)監(jiān)聽(tīng)修改value的函數(shù)

const [inputValue, setInputValue] = useState('');
    const passwordChange = (value: string) => {
    setInputValue(value);
};
const onPasswordInput = (e: any) => {
    passwordChange(e?.target?.value || '');
};

然后綁定即可,綁定好了我們就可以正常顯示了,但是,如果輸入了非法字符,這時(shí)候我們需要通過(guò)攔截器攔截。

<Form.Item
...
rules={[
    {
      required: true,
      message: 'Password not empty',
    },
    ({ getFieldValue }) => ({
      validator(_, value) {
        passwordChange(value);
        if (PasswordForce.invaildWord) {
          return Promise.reject(
            new Error('Password contains invalid characters.'),
          );
        }
        return Promise.resolve();
      },
    }),
]}
...

好了,使用片結(jié)束,我們實(shí)現(xiàn)下吧。

組件編寫(xiě)

編寫(xiě)組件

import {
  getRuleMatchResult,
  IpasswordForce,
  IpasswordRule,
  isMatchForceResultConfig,
  matchResultConfig,
  passwordBreakKey,
} from '@/utils/passwordStrengthChecker';
import React, { CSSProperties } from 'react';
import { useEffect } from 'react';
import { useState } from 'react';
import styled from 'styled-components';

interface props {
  inputValue: string;
  color?: string;
  style?: CSSProperties;
  className?: string;
  customRule?: IpasswordRule[];
}
enum ForceMap {
  high = 'High',
  middle = 'Mid',
  low = 'Low',
}
const boolNumSum = (list: boolean[]) =>
  list.reduce<number>(
    (previousValue, currentValue) =>
      currentValue ? previousValue + 1 : previousValue,
    0,
  );

const passwordForce: (props: props) => {
  View: React.FC;
  invaildWord: boolean;
  force: IpasswordForce;
} = ({ inputValue, style = {}, className, customRule = [] }) => {
  const [force, setforce] = useState<IpasswordForce>(false);
  const [invaildWord, setIsInvaildWord] = useState(false);
  const inputValueLen = inputValue?.length || 0;
  const setData = () => {
    setforce(false);
    const isFirstWordUp = inputValue[0] === inputValue[0].toLocaleUpperCase();
    const ruleRsult = getRuleMatchResult(customRule, inputValue, undefined, '');
    const matchNum = boolNumSum(ruleRsult.list.map((e) => e[passwordBreakKey]));
    const matchResultConfig: matchResultConfig[] = [
      { min: 0, max: 32, matchNum: 1, value: 'low' },
      { min: 7, max: 32, matchNum: 2, value: 'middle' },
      { min: 7, max: 32, matchNum: 3, value: 'middle' },
      { min: 15, max: 32, matchNum: 3, value: 'high', need: isFirstWordUp },
    ];
    setIsInvaildWord(ruleRsult.invaildWord);
    matchResultConfig.forEach((config) => {
      isMatchForceResultConfig(config, matchNum, inputValueLen) &&
        setforce(config.value);
    });
  };
  useEffect(() => {
    inputValue ? setData() : setforce(false);
  }, [inputValue]);
  return {
    View: () =>
      force ? (
        <PasswordForceWrap {...{ style, className }}>
          {ForceMap[force]}
        </PasswordForceWrap>
      ) : (
        <></>
      ),
    invaildWord,
    force,
  };
};
export default passwordForce;

const PasswordForceWrap = styled.span`
  color: ${({ color }) => color ?? '#000'};
`;

數(shù)據(jù)結(jié)構(gòu)解析

  • list 規(guī)則的集合,每一個(gè)規(guī)則都有是否匹配到和規(guī)則名及已規(guī)則數(shù)據(jù)本身。
  • map 就是方便直接獲取對(duì)應(yīng)規(guī)則的數(shù)據(jù)。
  • matchCount 就是匹配到的字符數(shù)
  • invaildWord 可以根據(jù)這個(gè)來(lái)判斷是否有非法字符(超過(guò)規(guī)則本身規(guī)定的字符)

流程解析

這個(gè)其實(shí)就兩個(gè)流程

  • 根據(jù)輸入的值和規(guī)則獲取處理后的數(shù)據(jù),獲得的數(shù)據(jù)結(jié)構(gòu)如上面所示。
  • 然后再編寫(xiě)具體符合業(yè)務(wù)需求的config數(shù)據(jù)交給isMatchForceResultConfig函數(shù)去匹配設(shè)置強(qiáng)度

嗯。 業(yè)務(wù)代碼差不多就這么多了。 然后里面關(guān)于依賴那就是屬于基本不會(huì)改動(dòng)的代碼,基于下面底層的文件,在業(yè)務(wù)代碼我們可以配置出很復(fù)雜的校驗(yàn)器,這部分代碼我們可以在其他文件上實(shí)現(xiàn)。

底層代碼解析

讓我們來(lái)康康吧。

下面是純ts代碼,可以運(yùn)行任意框架哦。

passwordStrengthChecker.ts

import { numberList, specialList, wordList } from './constants';

type map = <U, T>(opstion: {
  array: U[];
  range: number;
  matchList: T[];
  tokenMap: (updateItem: T, token: U, index: number) => T;
  breakKey?: string;
  arrayMap?: (item: U, index: number) => void;
}) => T[];

/**
 * match array and set
 */
export const setArrayMatch: map = ({
  array,
  range,
  matchList,
  breakKey,
  tokenMap,
  arrayMap,
}) => {
  const tokenLen = array.length;
  for (let tokenIndex = tokenLen - 1; tokenIndex >= 0; tokenIndex--) {
    const arrayToken = array[tokenIndex];
    arrayMap && arrayMap(arrayToken, tokenIndex);
    for (let findIndex = range - 1; findIndex >= 0; findIndex--) {
      matchList = matchList.map((item) =>
        tokenMap(item, arrayToken, findIndex),
      );
    }
    if (breakKey && !matchList.map((e) => (e as any)[breakKey]).includes(false))
      break;
  }
  return matchList;
};

export const passwordBreakKey = 'isMatch';
export type IpasswordRule = {
  list: string[];
  isMatch: boolean;
  name: string;
};
export const defaultPasswordRuleList = [
  { name: 'special', list: specialList },
  { name: 'num', list: numberList },
  { name: 'word', list: wordList },
];

type PickValue<T, K extends keyof T> = T[K];

export const getRuleMatchResult: (
  customRule: IpasswordRule[],
  inputValue: string,
  disableDefaultRule?: boolean,
  breakKey?: string,
) => {
  list: IpasswordRule[];
  map: Map<PickValue<IpasswordRule, 'name'>, boolean>;
  matchCount: number;
  invaildWord: boolean;
} = (customRule, inputValue, disableDefaultRule = true, breakKey) => {
  let ruleList = [
    ...(disableDefaultRule ? defaultPasswordRuleList : []),
    ...customRule,
  ].map((item) => ({ ...item, [passwordBreakKey]: false }));
  const range = Math.max(...ruleList.map((ruleItem) => ruleItem.list.length));
  let matchCount = 0;
  ruleList = setArrayMatch<string, IpasswordRule>({
    array: inputValue.split(''),
    range,
    matchList: ruleList,
    // not breakKey  full match
    breakKey: breakKey === void 0 ? passwordBreakKey : breakKey,
    tokenMap: (ruleItem, inputToken, findIndex) => {
      const match = ruleItem?.list[findIndex] === inputToken;
      if (match) {
        matchCount++;
        return { ...ruleItem, isMatch: true };
      }
      return ruleItem;
    },
  });
  return {
    list: ruleList,
    map: new Map(ruleList.map((e) => [e.name, e[passwordBreakKey]])),
    matchCount,
    // 想要獲取這個(gè)值,必須breakKey設(shè)置為空字符,如果提前退出會(huì)導(dǎo)致提前中止條件
    // To get this value, breakkey must be set to null string
    invaildWord: matchCount !== inputValue.length,
  };
};

export const isMatchForceResultConfig = (
  config: matchResultConfig,
  matchNum: number,
  inputValueLen: number,
) => {
  return (
    matchNum === config.matchNum &&
    inputValueLen >= config.min &&
    inputValueLen <= config.max &&
    (config.need !== undefined ? config.need : true)
  );
};

export type matchResultConfig = {
  min: number;
  max: number;
  matchNum: number;
  value: IpasswordForce;
  need?: boolean;
  back?: IpasswordForce;
};
export type IpasswordForce = false | 'high' | 'middle' | 'low';

流程就是合并規(guī)則,一個(gè)是默認(rèn)規(guī)則一個(gè)是自定義規(guī)則,如果自定義規(guī)則,那么就會(huì)覆蓋默認(rèn)規(guī)則。
從規(guī)則中,尋找規(guī)則數(shù)量最長(zhǎng)的規(guī)則,因?yàn)榈认挛覀儽闅v的時(shí)候可以合并所有的規(guī)則,不管多少規(guī)則,其實(shí)遍歷數(shù)是區(qū)別不大的。

遍歷函數(shù)是個(gè)單獨(dú)的高階函數(shù),可以自定義處理內(nèi)部的邏輯,這時(shí)候,我們匹配到了之后對(duì)應(yīng)的規(guī)則,激活對(duì)應(yīng)規(guī)則的屬性,并累計(jì)匹配到的字符。

最后正常全部匹配到了就應(yīng)該中止遍歷,但是有一個(gè)情況是不能中止的,那就是需要判斷是否有非法字符。

最后這個(gè)函數(shù)把處理過(guò)的數(shù)據(jù)丟給上層組件,流程就是這樣

在數(shù)據(jù)拋出的過(guò)程中,有些場(chǎng)景可能需要對(duì)對(duì)應(yīng)規(guī)則的數(shù)據(jù)進(jìn)行特殊處理,但是如果是array結(jié)構(gòu)就很不方便,于是拋出的數(shù)據(jù)應(yīng)該分為list和map類型,上層應(yīng)用想要獲取對(duì)應(yīng)規(guī)則的情況可以map.get(規(guī)則名稱)來(lái)操作

constants.ts

export const specialList = ["~", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "=", "-", "/", ",", ".", "?", "<", ">", ";", ":", "[", "]", "{", "}", "|", "\\"];
export const numberList = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'];
export const wordList = ["q", "a", "z", "w", "s", "x", "e", "d", "c", "r", "f", "v", "t", "g", "b", "y", "h", "n", "u", "j", "m", "i", "k", "o", "l", "p", "Q", "A", "Z", "W", "S", "X", "E", "D", "C", "R", "F", "V", "T", "G", "B", "Y", "H", "N", "U", "J", "M", "I", "K", "O", "L", "P"];

其他

很多人可能會(huì)有疑問(wèn),一個(gè)代碼檢測(cè)器有必要搞這么復(fù)雜嗎,直接正則不好嗎。其實(shí)從實(shí)用角度來(lái)說(shuō),確實(shí)正則更方便點(diǎn),但是有時(shí)候我們不想要循規(guī)蹈矩,或者想要手動(dòng)編碼的快感,或者要從無(wú)聊中代碼獲得更多的可玩性等,于是編寫(xiě)一個(gè)看起來(lái)挺復(fù)雜的代碼,不過(guò)把底層的封裝住,然后保留靈活性,在業(yè)務(wù)層里面盡量簡(jiǎn)單點(diǎn),其實(shí)也不是不可以試試的,但是也會(huì)在review的時(shí)候被懟,各位看官拷貝請(qǐng)注意哈,時(shí)間緊迫或者編碼能力不強(qiáng)的不建議使用本代碼,出問(wèn)題本人概不負(fù)責(zé)。

總結(jié)

到此這篇關(guān)于react如何實(shí)現(xiàn)一個(gè)密碼強(qiáng)度檢測(cè)器的文章就介紹到這了,更多相關(guān)react密碼強(qiáng)度檢測(cè)器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React 服務(wù)器組件的使用方法詳解

    React 服務(wù)器組件的使用方法詳解

    最近,React 服務(wù)器組件受到了廣泛的關(guān)注和熱捧,這是因?yàn)?nbsp;React 服務(wù)器組件允許開(kāi)發(fā)人員將與組件相關(guān)的任務(wù)外包給服務(wù)器,在本文中,我們將討論什么是 React 服務(wù)器組件,以及如何將它們集成到構(gòu)建應(yīng)用程序中,需要的朋友可以參考下
    2023-10-10
  • 基于webpack開(kāi)發(fā)react-cli的詳細(xì)步驟

    基于webpack開(kāi)發(fā)react-cli的詳細(xì)步驟

    這篇文章主要介紹了基于webpack開(kāi)發(fā)react-cli的詳細(xì)步驟,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-06-06
  • 在?React?中使用?i18next的示例

    在?React?中使用?i18next的示例

    這篇文章主要介紹了在?React?中使用?i18next,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-01-01
  • React實(shí)現(xiàn)二級(jí)聯(lián)動(dòng)的方法

    React實(shí)現(xiàn)二級(jí)聯(lián)動(dòng)的方法

    這篇文章主要為大家詳細(xì)介紹了React實(shí)現(xiàn)二級(jí)聯(lián)動(dòng)的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • React路由渲染方式與withRouter高階組件及自定義導(dǎo)航組件應(yīng)用詳細(xì)介紹

    React路由渲染方式與withRouter高階組件及自定義導(dǎo)航組件應(yīng)用詳細(xì)介紹

    這篇文章主要介紹了React路由三種渲染方式、withRouter高階組件、自定義導(dǎo)航組件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-09-09
  • React中條件渲染的常見(jiàn)方法總結(jié)

    React中條件渲染的常見(jiàn)方法總結(jié)

    條件渲染在React開(kāi)發(fā)中非常重要的功能,它允許開(kāi)發(fā)人員根據(jù)條件控制渲染的內(nèi)容,在創(chuàng)建動(dòng)態(tài)和交互式用戶界面方面發(fā)揮著至關(guān)重要的作用,本文總結(jié)了常用的的條件渲染方法,需要的朋友可以參考下
    2024-01-01
  • React條件渲染實(shí)例講解使用

    React條件渲染實(shí)例講解使用

    在React中,你可以創(chuàng)建不同的組件來(lái)封裝各種你需要的行為。然后還可以根據(jù)應(yīng)用的狀態(tài)變化只渲染其中的一部分。React 中的條件渲染和JavaScript中的一致,使用JavaScript操作符if或條件運(yùn)算符來(lái)創(chuàng)建表示當(dāng)前狀態(tài)的元素,然后讓React根據(jù)它們來(lái)更新UI
    2022-11-11
  • React中使用Mobx的方法

    React中使用Mobx的方法

    Mobx是一個(gè)前端“狀態(tài)管理框架”,狀態(tài)管理就是將分布在各個(gè)組件、各個(gè)模塊中的狀態(tài)的變化,按照一定的規(guī)則,進(jìn)行統(tǒng)一的管理,這篇文章主要介紹了React中如何使用Mobx,需要的朋友可以參考下
    2023-02-02
  • React 三大屬性之state的使用詳解

    React 三大屬性之state的使用詳解

    這篇文章主要介紹了React 三大屬性之state的使用詳解,幫助大家更好的理解和學(xué)習(xí)使用React,感興趣的朋友可以了解下
    2021-04-04
  • React18?中的?Suspense?API使用實(shí)例詳解

    React18?中的?Suspense?API使用實(shí)例詳解

    這篇文章主要為大家介紹了React18?中的?Suspense?API使用實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10

最新評(píng)論

衢州市| 中西区| 香格里拉县| 黄石市| 石首市| 洪江市| 日照市| 重庆市| 东宁县| 缙云县| 含山县| 开远市| 锦屏县| 旬邑县| 平果县| 中方县| 镇远县| 祁连县| 塘沽区| 南和县| 滨州市| 枣庄市| 托里县| 葵青区| 新蔡县| 桑植县| 泰兴市| 龙门县| 南康市| 南丹县| 河津市| 习水县| 浪卡子县| 罗田县| 偏关县| 马关县| 筠连县| 芦溪县| 北京市| 安溪县| 曲麻莱县|