這篇文章會包含以下幾個小知識點:html
{ 'zh-cn': 1, 'eng': 1 }
,默認中英文都是一個字符長度。下面我就記錄一下我爲何想要寫這個組件的心路歷程:html5
首先,我其實只是想寫一個debounce input。緣由有如下幾點:node
<BestInput
label='類型校驗'
style={{ width: '40%' }}
timer={600} /*上面的示例沒有timer屬性,這裏設置用戶在600ms內沒其餘輸入再監聽*/
error={this.state.emailTrue}
errMsg='這不是一個合法的郵箱'
onChange={this.handleRegExp}
/>
複製代碼
效果以下:react
固然,不用input就不能完成上面的效果了嗎?固然能夠,你能夠在普通的input裏使用onBlur來進行輸入的校驗,也就是說輸入完成當窗口失焦才校驗,也能夠實現用戶輸入完成進行校驗的效果。可是,若是你須要動態監聽input的變化,就須要使用onChange,若是你還增長校驗,就須要額外寫一個onBlur,而如今你只須要一個onChange就能夠知足兩個要求。webpack
公司的項目就不上截圖了,你們明白個人意思就好,O(∩_∩)O哈哈~。無非就是少幾回沒必要要的請求,微微的提高一下性能~我一直以爲,即便是0.001ms的提高,也是很重要的。git
[實現]:實現一個debounce input其實很簡單,不過在實際應用場景中,有不少都須要debounce的狀況,不是隻有input能夠debounce,具體的能夠參照lodash的debounce函數,讀讀源碼也可根據本身的實際場景再開發。我這裏就只講怎麼debounce input了。github
沒錯,其實就是這麼簡單,咱們想要在用戶600ms後不繼續輸入了再獲取input的value,就是設一個600ms的setTimeout,而後在裏面獲取值。當用戶不斷輸入觸發setTimeout的時候,再經過clearTimeout進行重置定時器並從新計時,這樣就很簡單的實現了咱們的需求。web
// 下面是普通的js實現,能夠參考一下
// 獲取input元素
var textInput = document.getElementById('test-input');
// 初始化一個定時器函數
var timeout = null;
textInput.onkeyup = function (e) {
// 不斷重置定時器函數
clearTimeout(timeout);
// 500ms內沒任何其餘輸入,獲取debounce以後的結果
timeout = setTimeout(function () {
console.log('Input Value:', textInput.value);
}, 500);
};
複製代碼
重點來了,做爲一個剛畢業的職場小白,公司的流程還不是很熟悉,進入公司無非就是作業務。評審—>排期->開發->上線,期間可能會包含着產品屢次的改需求,哈哈,我並非針對產品哦~所以,對於我來講,我所作的是我應該作的業務,但可能並非我想作的業務。可是,每作一個需求,我以爲仍是須要思考的,爲何要這麼作,爲何要改爲這樣,產品確定有本身的想法,可能這麼作更符合用戶的邏輯等等。
廢話很少說,開始進入正題,囉嗦一大堆跟這篇文章有啥關係,固然有關係了,沒看到小標題嗎?產品驅動業務!項目裏有這麼一個需求:
獲取用戶輸入的內容,而後不能超過10個字符,可是其中中文字符算1個,英文字母和數字算0.5個
。
確實不是一個複雜的需求,獲取輸入的內容正則匹配一下而後從新計算length返回就行了,那麼問題來了,若是多個組件都用到這個需求了可是要求又不同呢?好比頁面A要求中文1個英文也是1個,頁面B要求中文是2個英文是1個。那豈不是每個都要配套寫對應的函數。因此,順便的,我把這個需求也加到了react-best-input裏,能夠經過配置屬性charBase來進行字符的修改,而後經過getLength獲取自定義的輸入長度。npm
charBase {
'zh-cn': number//中文字符長度,
'eng': number//英文字符長度
}
getLength(length) // 獲取自定義長度
複製代碼
開發完了,該發佈組件到npm了,步驟特別簡單,首先就是配置好webpack的各類配置,每一個人配置都不同,能夠參考各類文檔配置一個適合你的就能夠,我就不介紹了,由於我也在進修中,O(∩_∩)O哈哈~。redux
這裏多說一句啊,webpack4+默認就是壓縮代碼,也就是自帶uglifyJs的功能,所以,你若是在開發的時候,可使用
webpack --mode devlopment
進行打包查看打包後的代碼,也能夠參照個人配置。
這裏有個小坑,本地測試必須使用雙引號引用包名稱,不然會報錯,也就是
yarn link "react-best-input"
才能夠。
yarn publish
命令來進行發佈,固然你須要先在npm上註冊本身的帳號才能夠,註冊的過程就很少說了。第一次發佈須要你的登陸信息,以後就會發布你的包。
這裏也有一個小坑:npm註冊的時候郵箱好像不能用國內的郵箱,要否則提示錯誤,沒測試過,可是我用126郵箱註冊了五次都沒成功,而使用gmail郵箱註冊了一次就成功了,相同的帳戶名密碼。。。
若是沒有使用原生的js編寫包,使用的是react語法寫的,那麼在webpack的時候須要使用babel轉譯成es5代碼才能夠。須要使用babel-preset-react,babel-preset-es2015和babel-preset-stage-1。
服務端渲染,很火的一個詞,也可能大部分項目都在用了,我是想說的不是這個問題,我想說的是若是你寫的組件用到了底層諸如window,document這些變量的話,那麼在服務端渲染是過不去的,通常來講是node端,node端是沒有上面兩個變量的。由於我用的是input,而且使用了樣式,style-loader會使用底層的document.querySelector來查找dom節點插入樣式,所以這個包在服務端渲染的時候會報錯:window is not defined.
。
[解決辦法]:兵來將擋,水來土屯。其實就是異步加載組件唄,這種組件通常來講也不必在服務端渲染出來因此目前個人解決辦法就是使用webpack的import()方法對組件進行異步加載,這樣就沒問題了。所以,我又額外寫了一個異步加載的組件,有須要的話直接拿來用就能夠了:rc-async-component。這裏應該叫react-async-component的,可是奈何被人家一個月前註冊了,因此說提早搶個好名字有用啊,哈哈。
...
import asyncComponent from 'rc-async-component';
...
const BestInput = asyncComponent(() => import('react-best-input'));
...
render() {
return (
<BestInput />
)
}
複製代碼
強調一下,非服務端渲染直接就可使用,沒有任何問題,服務端渲染目前須要用異步加載的方式,可能後續有更好的解決辦法到時候會更新文檔。
若是看到這還能堅持看下去,我真的感謝大家了,感受本身水平有限,會不斷提升的!我以爲對一我的有幫助也是有意義的事情,O(∩_∩)O哈哈~
若是您喜歡,謝謝star,我會很是開心