React16.13 簡(jiǎn)單封裝一個(gè)input組件
input組件
- GInput.jsx
import React from 'react'
import './GInput.css'
// props 參數(shù):
// --props
// ------可選:type defaultValue placeholder readOnly disabled
// ------可選:trim:"true" 過濾前后空格 className
// ------可選:rule:{ regx:RegExp | function, [callback: function, errorMsg: ''] } 驗(yàn)證規(guī)則
// ------必選:onInput input事件函數(shù),通過這個(gè)函數(shù)獲取修改后的input值value
// --自定義屬性以data-*方式定義
class GInput extends React.Component {
constructor (props) {
super();
let errMsg = ''
if (props.rule) {
errMsg = props.rule.errorMsg || ''
}
let attrs = {}
attrs = this.getOptionsAttrs(props)
this.state = {
val: null,
attrs: attrs,
className: props.className || '',
hasError: this.regxRule(props, props.defaultValue || props.value),
errorMsg: errMsg
}
this.handleInputChange = this.handleInputChangeFn.bind(this)
}
hasRule (props) {
let flag = ''
if (props.rule) {
if (props.rule.regx instanceof RegExp) {
flag = 'RegExp'
}
else if (typeof props.rule.regx === 'function') {
flag = 'function'
}
}
return flag
}
regxRule (props, expValue) {
expValue = expValue || ''
// console.log('expValue:', expValue, ' flag:', props.rule.regx.test(expValue))
let error = false
let ruleFlag = this.hasRule(props)
if (ruleFlag) {
let flag;
if(ruleFlag === 'RegExp') {
flag = new RegExp(props.rule.regx).test(expValue)
}
else if (ruleFlag === 'function') {
flag = props.rule.regx(expValue)
}
if (!flag) {
error = true
}
if (typeof props.rule.callback === 'function') {
props.rule.callback(flag)
}
}
return error
}
handleInputChangeFn(event) {
// console.log(event.target.value)
let val = event.target.value
if (typeof this.props.onInput === 'function') {
if(this.props.trim === 'true') {
val = val.replace(/^\s*|\s*$/g,'')
event.target.value = val
}
if (typeof val === 'string' && val !== this.state.val) {
// 如果設(shè)置了trim:"true",每次輸入空格的時(shí)候,都會(huì)過濾,value一直都是''
// 這種情況下,只需要第一次更新一下空值,后面的空值就不需要再更新了
// 下面的代碼就是為了達(dá)到這個(gè)目的,防止每次空值都更新
this.props.onInput(val)
this.setState({
val: val
})
}
this.setState({
hasError: this.regxRule(this.props, val)
})
} else {
console.error('<GInput> has no onInput event.')
}
}
// type onInput className value屬性是直接寫在input標(biāo)簽中的,rule, trim屬性是不需要直接寫在屬性中的
// 其他的屬性,包括自定義屬性,都以 attrs 解構(gòu)賦值的方式寫入input屬性中
getOptionsAttrs (props) {
let obj = {}
let keyArr = Object.keys(props)
let requiredOptions = 'onInput|type|rule|trim|className|value'
let key = ''
for(let i = 0; i < keyArr.length; i++) {
key = keyArr[i]
if(requiredOptions.indexOf(key) > -1) {
continue
}
// console.log(key)
obj[key] = props[key]
}
return obj
}
render () {
return (
<div className={'g-input-box ' + this.state.className + (this.state.hasError? ' error':'')}>
{/* <input className='g-input'
readOnly={this.state.readOnly}
disabled={this.state.disabled}
type={this.props.type || 'text'}
placeholder={this.props.placeholder}
defaultValue={this.props.defaultValue}
onInput={this.handleInputChange}/> */}
{
this.props.value ?
(
<input className='g-input'
{...this.state.attrs}
type={this.props.type || 'text'}
value={this.props.value}
onInput={this.handleInputChange}/>
)
:
(
<input className='g-input'
{...this.state.attrs}
type={this.props.type || 'text'}
onInput={this.handleInputChange}/>
)
}
{
this.state.hasError && (
<div className="error-msg">{this.state.errorMsg}</div>
)
}
</div>
)
}
}
export default GInput;
組件同目錄下的樣式
html, body {
height: 100%; padding: 0; margin: 0;
}
/*GInput*/
.g-input-box > .g-input {
border: 1px solid #666;
}
.g-input-box.error > .g-input {
border: 1px solid #f00;
}
.g-input-box.error > .error-msg, .g-input-box.error > .g-input {
color: #f00;
}
組件的引用頁(yè)面
import React, { Component } from "react";
import GInput from './components/form/GInput.jsx'
class About extends Component {
constructor(props) {
super();
this.state={
form: {
input123: 'abc',
pwd: '12s3'
},
rules: {
input123Rule: {
regx: /^[a-z]*$/g,
callback: function (flag) {
console.log('input123Rule:', flag)
}
},
pwdRule: {
regx: function (val) {
if (val > 100 && val < 10000) {
return true
} else {
return false
}
},
callback: function (flag) {
console.log('pwdRule:', flag)
},
errorMsg: '只能輸入100-10000之間的數(shù)字'
}
}
}
}
UNSAFE_componentWillMount () {}
componentDidMount () {}
handleInput123Change (val) {
console.log('handleInput123Change:', val)
}
render () {
return (
<div>
<h1>About page</h1>
<GInput type="text" className="my-input-123"
trim={true}
disabled={false}
placeholder="只能輸入小寫字母"
rule={this.state.rules.input123Rule}
onInput={this.handleInput123Change}></GInput>
<GInput type="text" className="my-input-123"
trim={true}
defaultValue={this.state.form.pwd}
rule={this.state.rules.pwdRule}
onInput={this.handleInput123Change}></GInput>
</div>
)
}
}
export default About;
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。