精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

圖形編輯器開(kāi)發(fā):實(shí)現(xiàn)自定義規(guī)則輸入框組件

開(kāi)發(fā) 前端
除了數(shù)字和顏色值輸入框,CustomRuleInput 在圖形編輯器中用到的地方非常多,邏輯也不復(fù)雜,相比普通 Input,多加一個(gè)校驗(yàn)補(bǔ)正的 Parser 算法。

圖形編輯器中,雖然編輯器內(nèi)核本身很重要,但相當(dāng)大的一部分工作是 UI 層的交互實(shí)現(xiàn)。

其中很重要的交互功能是用戶可以 通過(guò)輸入框去修改一些屬性

不同類(lèi)型的輸入框有著各自的規(guī)則,今天我們來(lái)看看怎么去實(shí)現(xiàn)這么一個(gè) 自定義規(guī)則輸入框 React 組件

需求

我們需要做一個(gè)自定義規(guī)則輸入框。它需要支持的核心功能是,失焦時(shí)

  • 嘗試對(duì)輸入的內(nèi)容進(jìn)行校驗(yàn)和補(bǔ)正,將得到的合法值去更新數(shù)據(jù)源;
  • 上述操作后,如果無(wú)法得出合法值,恢復(fù)上一次的合法輸入;

一些次要的功能:

  • 按下回車(chē)時(shí)自動(dòng)失焦;
  • 點(diǎn)在輸入框時(shí),自動(dòng)全選。

我之前的一篇文章講述過(guò)一個(gè)場(chǎng)景,即用戶輸入 hex 格式的顏色值時(shí),應(yīng)該如何實(shí)現(xiàn) hex 的校驗(yàn)補(bǔ)正算法,去拿到一個(gè)合法的值。

當(dāng)時(shí)只說(shuō)了校驗(yàn)補(bǔ)正算法。這篇文章是它的一個(gè)補(bǔ)充,即去實(shí)現(xiàn)這么一個(gè)自定義規(guī)則組件,這個(gè)組件可以裝配不同格式對(duì)應(yīng)的校驗(yàn)補(bǔ)正算法。

組件實(shí)現(xiàn)

首先是 props 的設(shè)計(jì)。

  • value:外部傳入的值,如果 props.value 發(fā)生改變,輸入框要立即改變。
  • parser:轉(zhuǎn)換算法,會(huì)拿到輸入框的字符串內(nèi)容。函數(shù)的返回值返回值如果是 false,表示不合法;如果是字符串,這個(gè)字符串會(huì)通過(guò) props.onBlue 方法傳遞給調(diào)用者。
  • onBlur:轉(zhuǎn)換成功后會(huì)被調(diào)用,在這里可以拿到最后的合法值。(感覺(jué) onChange 命名會(huì)不會(huì)更好)
interface ICustomRuleInputProps {
  parser: (newValue: string, preValue: string | number) => string | false;
  value: string | number;
  onBlur: (newValue: string) => void;
}

這里選擇非受控組件的做法,用一個(gè) inputRef 變量拿到 input 元素,通過(guò) inputRef.current.value 去讀寫(xiě)內(nèi)容。

不多說(shuō),給出實(shí)現(xiàn)。

import { FC, useEffect, useRef } from 'react';

interface ICustomRuleInputProps {
  parser: (newValue: string, preValue: string | number) => string | false;
  value: string | number;
  onBlur: (newValue: string) => void;
}

export const CustomRuleInput: FC<ICustomRuleInputProps> = ({
  value,
  onBlur,
  parser
}) => {
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    if (inputRef.current) {
      // 如果 props.value 改變,input 的內(nèi)容無(wú)條件同步
      inputRef.current.value = String(value);
    }
  }, [value]);

  return (
    <input
      ref={inputRef}
      defaultValue={value}
      notallow={() => {
        // 點(diǎn)在 input 上,會(huì)自動(dòng)全選輸入框內(nèi)容
        inputRef.current.select();
      }}
      notallow={(e) => {
        // enter 時(shí)觸發(fā)失焦(注意中文輸入法下按下 enter 不要失焦)
        if (e.key === 'Enter' && !e.nativeEvent.isComposing) {
          e.currentTarget.blur();
        }
      }}
      notallow={(e) => {
        if (inputRef.current) {
          const str = inputRef.current.value.trim();
          // 檢驗(yàn)補(bǔ)正
          const newValue = parser(str, value);
          if (newValue !== false) { // 能拿到一個(gè)合法值
            e.target.value = String(newValue);
            onBlur(newValue);
          } else { // 拿不到合法值,恢復(fù)為上一次的合法值
            e.target.value = String(value);
          }
        }
      }}
    />
  );
};

線上 demo 地址:

https://codesandbox.io/s/hjmmz4

基于這個(gè)組件,我們可以擴(kuò)展各種特定效果的 input 組件。比如 NumberInput 和 ColorHexInput。

NumberInput 實(shí)現(xiàn)

下面就基于這個(gè) CustomRuleInput,擴(kuò)展一個(gè)數(shù)字輸入框 NumberInput 組件。

該組件接受的 props:

  • value:數(shù)據(jù)源。如果你有需求,這里可以做一層單位轉(zhuǎn)換,比如角度轉(zhuǎn)弧度;
  • min:最小值,如果小于 min,會(huì)修正為 min;
  • onBlur:數(shù)據(jù)改變相應(yīng)事件。

校驗(yàn)補(bǔ)正算法在 NumberInput 組件內(nèi)部實(shí)現(xiàn)。

const parser={(str) => {
  str = str.trim();
  
  // 字符串轉(zhuǎn)數(shù)字
  let number = Number(str);
  if (!Number.isNaN(number) && number !== value) {
    // 不能小于 min
    number = Math.max(min, number);
    console.log(number);
    return String(number);
  } else {
    return false;
  }
}}

完整實(shí)現(xiàn):

import { FC, useEffect, useRef } from 'react';
import { CustomRuleInput } from './CustomRuleInput';

interface INumberInputProps {
  value: string | number;
  min?: number;
  onBlur: (newValue: number) => void;
}

export const NumberInput: FC<INumberInputProps> = ({
  value,
  min = -Infinity,
  onBlur
}) => {
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    if (inputRef.current) {
      inputRef.current.value = String(value);
    }
  }, [value]);

  return (
    <CustomRuleInput
      parser={(str) => {
        str = str.trim();
        let number = parseToNumber(str);
        if (!Number.isNaN(number) && number !== value) {
          number = Math.max(min, number);
          console.log(number);
          return String(number);
        } else {
          return false;
        }
      }}
      value={value}
      notallow={(newVal) => onBlur(Number(newVal))}
    />
  );
};

用法:

const [num, setNum] = useState(123);

<NumberInput value={num} min={0} notallow={(val) => setNum(val)} />

效果:

ColorHexInput

然后是十六進(jìn)制顏色輸入框。

這個(gè)算法我們?cè)谥暗奈恼轮v過(guò)了。

直接看組件實(shí)現(xiàn):

import { FC, useEffect, useRef } from 'react';
import { CustomRuleInput } from './CustomRuleInput';

interface IProps {
  value: string;
  onBlur: (newValue: string) => void;
}

/**
 * 補(bǔ)正為 `RRGGBB` 格式
 *
 * reference: https://mp.weixin.qq.com/s/RWlsT-5wPTD7-OpMiVhqiA
 */
export const normalizeHex = (hex: string) => {
  hex = hex.toUpperCase();
  const match = hex.match(/[0-9A-F]{1,6}/);
  if (!match) {
    return '';
  }
  hex = match[0];

  if (hex.length === 6) {
    return hex;
  }
  if (hex.length === 4 || hex.length === 5) {
    hex = hex.slice(0, 3);
  }
  // ABC -> AABBCC
  if (hex.length === 3) {
    return hex
      .split('')
      .map((c) => c + c)
      .join('');
  }
  // AB => ABABAB
  // A -> AAAAAA
  return hex.padEnd(6, hex);
};

export const ColorHexInput: FC<IProps> = ({ value, onBlur, prefix }) => {
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    if (inputRef.current) {
      inputRef.current.value = String(value);
    }
  }, [value]);

  return (
    <CustomRuleInput
      parser={(str, prevStr) => {
        str = str.trim();
        // check if it is a valid hex and normalize it
        str = normalizeHex(str);
        if (!str || str === prevStr) {
          return false;
        }
        return str;
      }}
      value={value}
      notallow={(newVal) => onBlur(newVal)}
    />
  );
};

結(jié)尾

除了數(shù)字和顏色值輸入框,CustomRuleInput 在圖形編輯器中用到的地方非常多,邏輯也不復(fù)雜,相比普通 input,多加一個(gè)校驗(yàn)補(bǔ)正的 parser 算法。

責(zé)任編輯:姜華 來(lái)源: 前端西瓜哥
相關(guān)推薦

2024-01-08 08:30:05

光標(biāo)圖形編輯器開(kāi)發(fā)游標(biāo)

2023-10-19 10:12:34

圖形編輯器開(kāi)發(fā)縮放圖形

2011-03-17 09:45:01

Spring

2023-09-26 07:39:21

2010-11-16 13:21:08

Oracle命令行

2023-09-07 08:24:35

圖形編輯器開(kāi)發(fā)繪制圖形工具

2023-08-31 11:32:57

圖形編輯器contain

2023-04-07 08:02:30

圖形編輯器對(duì)齊功能

2023-02-01 09:21:59

圖形編輯器標(biāo)尺

2009-06-24 15:13:36

自定義JSF組件

2023-09-11 09:02:31

圖形編輯器模塊間的通信

2023-04-10 08:45:44

圖形編輯器排列移動(dòng)功能

2023-10-10 16:04:30

圖形編輯器格式轉(zhuǎn)換

2023-10-08 08:11:40

圖形編輯器快捷鍵操作

2023-08-28 08:10:50

Hex圖形編輯器

2022-12-07 08:56:27

SpringMVC核心組件

2023-01-03 07:40:27

自定義滑塊組件

2022-03-01 16:09:06

OpenHarmon鴻蒙單選組件

2020-09-24 14:06:19

Vue

2023-07-07 13:56:01

圖形編輯器畫(huà)布縮放
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

欧美精品九九久久| 欧美日韩加勒比精品一区| 国产欧美亚洲精品| 欧美日韩精品亚洲精品| 国产欧美自拍一区| 日本久久一区二区三区| 亚洲av首页在线| 人人妻人人澡人人爽人人欧美一区| 99热这里只有成人精品国产| 亚洲欧美国产另类| 免费不卡av网站| 超级碰碰久久| 亚洲女性喷水在线观看一区| 久久99精品久久久久子伦| 中文字幕一区二区人妻痴汉电车| 欧美日本免费| 少妇高潮久久77777| 亚洲av无码专区在线播放中文| 欧美gay视频| 亚洲美女在线一区| 日韩欧美亚洲在线| 天天干天天做天天操| 精品一区二区三区免费视频| 欧美一级免费看| 日本老熟俱乐部h0930| 亚洲欧洲免费| 欧美精品一区在线观看| www.99r| 天堂中文av在线资源库| 一区二区三区精品| 亚洲欧美日韩精品久久久| 婷婷在线免费观看| 国内成人精品2018免费看| 日本精品久久久| 欧美另类视频在线观看| 日韩一区自拍| 亚洲欧美中文日韩在线v日本| 午夜视频在线免费看| 久久er热在这里只有精品66| 日韩欧美999| 丝袜人妻一区二区三区| 四虎亚洲精品| 中文字幕一区二区在线观看| 日韩精品无码一区二区三区| 亚洲色偷精品一区二区三区| 成人av综合一区| www.久久艹| 国产人妖一区二区| 九九久久精品视频| 国产精品久久久久不卡| 日韩黄色片网站| 在线亚洲免费| 91av视频导航| 午夜毛片在线观看| 亚洲乱码视频| 91高清免费在线观看| 国产无遮挡免费视频| 国内成人在线| 国内揄拍国内精品少妇国语| 国产一级一级片| 亚洲性视频h| 久久乐国产精品| 日韩久久精品视频| 99精品视频免费观看视频| 久久免费精品视频| 中文字幕一区二区三区精品| 亚洲精品日韩久久| 69久久夜色精品国产69| 西西44rtwww国产精品| 国产精品毛片一区二区三区| 91成人在线播放| 男人天堂av在线播放| 亚洲欧美久久| 国产精品女人久久久久久| 一二三四区在线| 国产河南妇女毛片精品久久久 | 欧美激情一区二区三区在线视频 | 久久精品国产福利| 欧美乱妇15p| 精品国产乱码久久久久夜深人妻| 久久香蕉网站| 亚洲欧美日韩久久久久久| 免费在线观看a视频| 91一区二区三区四区| 美女少妇精品视频| 国产乡下妇女做爰毛片| 久久久久国产精品一区二区| 国产精品久久久久久av福利| 一炮成瘾1v1高h| 国产精品123| 久久久久久国产精品mv| 91最新在线| 伊人性伊人情综合网| 鲁一鲁一鲁一鲁一澡| 精品亚洲美女网站| 日韩精品资源二区在线| 精品人妻少妇嫩草av无码| 欧美大片aaaa| 性亚洲最疯狂xxxx高清| 亚洲一卡二卡在线| 国产aⅴ精品一区二区三区色成熟| 国产一区二区三区高清| 秋霞成人影院| 懂色av中文一区二区三区天美 | 一级做a爰片久久毛片| 国产综合色精品一区二区三区| 国产精品一区二区免费看| 黄色在线视频观看网站| 亚洲综合免费观看高清完整版 | 日韩国产成人在线| 丁香啪啪综合成人亚洲小说 | 欧美日本免费一区二区三区| yjizz视频| 久久婷婷蜜乳一本欲蜜臀| 91极品女神在线| 99在线小视频| 国产精品色一区二区三区| 欧美 日韩 国产 高清| 国产乱码精品一区二区三区亚洲人 | 国产精品短视频| 欧美 日韩 国产在线观看| 免费一级欧美在线观看视频| 国产视频亚洲精品| 久久精品国产亚洲AV无码麻豆 | 欧美一区二区三区在线观看免费| 亚洲大片在线观看| aaa一级黄色片| 欧美日韩一区二区综合 | 成人mm视频在线观看| 国产视频精品一区二区三区| 久青草免费视频| 国产福利91精品一区二区三区| 一区二区精品免费视频| 依依综合在线| 日韩电影网在线| 国产网址在线观看| 国产一区二区在线观看免费| 亚洲精品第一区二区三区| 三上悠亚亚洲一区| 国产丝袜精品视频| 亚洲午夜18毛片在线看| 成人免费高清在线| 老子影院午夜伦不卡大全| 久久九九精品视频| 久久九九国产精品怡红院| 中文字幕精品一区二区精| 日本一区二区免费在线 | 精品免费av在线| 亚洲欧美日韩在线一区| 男人日女人网站| 久久久亚洲精品石原莉奈| 欧美牲交a欧美牲交aⅴ免费真| 欧美大胆视频| 欧美中文字幕第一页| 五月婷中文字幕| 色综合欧美在线视频区| 欧美狂猛xxxxx乱大交3| 首页国产欧美日韩丝袜| 欧美一区1区三区3区公司| 手机看片久久| 神马久久久久久| 国产婷婷在线视频| 亚洲一区二区偷拍精品| 波多野结衣影院| 久久aⅴ乱码一区二区三区| 欧洲精品在线一区| av成人在线观看| 美日韩精品视频免费看| 国产成人精品白浆久久69| 亚洲一区二区在线免费看| 亚洲天堂av网站| 亚洲影音一区| 五月天亚洲综合| 99tv成人影院| 国外成人在线播放| 国产在线超碰| 91精品国产色综合久久不卡电影 | 精品91在线| 久久伊人一区二区| 国产资源一区| 久久人91精品久久久久久不卡| 亚洲色图欧美视频| 欧美在线视频日韩| 日韩欧美中文字幕视频| 91在线云播放| 免费一区二区三区在线观看 | 国产av无码专区亚洲精品| 欧美综合久久| 成人资源av| 成人自拍av| 欧美激情久久久| 国产一级网站视频在线| 欧美一三区三区四区免费在线看 | 超碰在线观看免费| 亚洲欧洲一区二区三区在线观看| 怡红院成永久免费人全部视频| 一区二区三区精品| 国产极品视频在线观看| 不卡av在线免费观看| 永久免费的av网站| 国产一区成人| 成年在线观看视频| 国产成人久久| 精品国产乱码久久久久久丨区2区 精品国产乱码久久久久久蜜柚 | 日产日韩在线亚洲欧美| 中文字幕在线三区| 最好看的2019的中文字幕视频| 秋霞网一区二区| 在线播放中文一区| 一级黄色av片| 婷婷成人激情在线网| 黄色a级片在线观看| 国产日韩欧美亚洲| 免费的av网站| 成人激情免费网站| 亚洲欧美一区二区三区不卡| 日韩二区在线观看| 女人和拘做爰正片视频| 国内精品久久久久久久97牛牛 | av亚洲在线| 欧美刺激脚交jootjob| 亚洲视频中文字幕在线观看| 午夜精品久久久久久久久| 中文字幕在线观看成人| 欧美国产一区二区在线观看| 黄色网址在线视频| 国产精品99久久久| 手机av在线网站| 三级精品在线观看| 日韩欧美视频网站| 亚洲人成免费| 老汉色影院首页| 日韩免费在线| 久久久久网址| 欧美尿孔扩张虐视频| 99在线视频首页| 中文字幕日本一区| 91夜夜未满十八勿入爽爽影院| 欧美性理论片在线观看片免费| 久久人人爽人人| 91九色国产在线播放| 欧美日韩成人在线播放| 国产乱色在线观看| 国产香蕉一区二区三区在线视频| 黄上黄在线观看| 日韩精品中文字幕在线播放| 色香蕉在线视频| 欧美不卡激情三级在线观看| 999久久久久| 91麻豆精品国产91久久久| 在线观看亚洲黄色| 欧美日韩一级二级| 怡春院在线视频| 欧美日韩亚洲综合在线 欧美亚洲特黄一级 | 激情久久综合网| 激情综合五月婷婷| 台湾佬美性中文| 不卡一区二区中文字幕| 肉丝美足丝袜一区二区三区四| 成人性生交大片免费看中文| 亚洲美女高潮久久久| 大陆成人av片| 久久精品无码专区| 不卡一区二区中文字幕| 国产精品久久AV无码| 国产精品一区二区在线播放| 亚洲视频天天射| 91论坛在线播放| 久久久久久九九九九九| 国产精品国产a级| 肉色超薄丝袜脚交69xx图片| 国产精品不卡一区| 麻豆国产尤物av尤物在线观看| 一级日本不卡的影视| 日韩免费一二三区| 色综合天天性综合| 中文字幕人妻一区二区在线视频 | 国产欧美日韩在线看| 日本美女xxx| 一个色综合网站| 成人免费视频毛片| 欧美视频第二页| 亚洲精品一区二区三区四区| 亚洲国产精品一区二区三区| 午夜视频在线免费播放| 色偷偷9999www| 污的网站在线观看| 91av视频在线| 精品国产亚洲一区二区三区在线| dy888夜精品国产专区| 亚洲欧美成人vr| 最新中文字幕久久| 亚洲国产婷婷| 国产wwwxx| av在线一区二区| 亚洲不卡的av| 亚洲国产精品人人做人人爽| 免费看日批视频| 91精品国产综合久久久久久久久久 | 99视频精品免费观看| 麻豆传传媒久久久爱| 国产成人aaaa| 国产123在线| 亚洲尤物视频在线| 在线观看免费黄色小视频| 欧美刺激脚交jootjob| 岛国大片在线观看| 97国产suv精品一区二区62| 精品久久在线| 黑人巨大精品欧美一区二区小视频| 日韩av久操| 国产免费黄视频| 国产一区亚洲一区| 亚洲一级片在线播放| 午夜激情一区二区| 国产口爆吞精一区二区| 在线播放国产精品| 爱啪啪综合导航| 91精品久久久久久蜜桃| 婷婷综合亚洲| 国产精品无码av无码| 国产福利精品导航| 在线看的片片片免费| 色94色欧美sute亚洲线路一ni| 国产91免费在线观看| 免费99精品国产自在在线| 成人免费网站www网站高清| 国产精品日韩一区二区| 欧美高清不卡| 激情五月婷婷基地| 国产日韩欧美麻豆| 久久精品无码av| 亚洲精品大尺度| 免费电影网站在线视频观看福利| 91亚洲精品久久久| 久久免费大视频| 人人爽人人av| 国产视频一区在线观看| 久久久久久久久久免费视频| 日韩欧美高清dvd碟片| 超碰免费在线播放| 国产美女直播视频一区| 波多野结衣一区| 91香蕉视频污版| 久久久99精品免费观看不卡| 日本午夜视频在线观看| 亚洲大胆人体在线| 久草在线资源站资源站| 国产精品日韩一区二区| 国内自拍视频一区二区三区| 国产91在线免费观看| 亚洲综合图片区| 丁香六月色婷婷| 久久99久久99精品中文字幕| 97久久亚洲| av在线观看地址| 91麻豆精东视频| 久久久久久在线观看| 亚洲男人天堂手机在线| jizzyou欧美16| 99精品视频网站| 国产一区999| 日本三级中文字幕| 日韩成人中文字幕| 精品丝袜在线| 欧美精品成人一区二区在线观看| 欧美一级网站| 香蕉久久久久久久| 欧美电影在线免费观看| 黄视频在线观看网站| 成人三级在线| 国产精品免费看| jizz日本免费| 欧美亚洲精品一区| 日本韩国在线视频爽| 国产成人精品一区二区三区福利| 欧美激情自拍| xxxxxx黄色| 欧美视频三区在线播放| 黄色网页在线播放| 91免费看片在线| 国产视频一区在线观看一区免费| 中文字幕成人动漫| 欧美一区二区在线播放| 51精品视频| 色综合视频二区偷拍在线| 福利电影一区二区三区| 国产精品人人人人| 久久视频中文字幕| 久久国产精品免费精品3p| 国产精品第12页| 亚洲在线视频一区| 日本福利片在线| 91成人免费视频| 免费在线观看成人av| 日韩一卡二卡在线观看| 日韩高清人体午夜| 91欧美精品| 中国丰满熟妇xxxx性| 国产欧美1区2区3区|