爲何咱們在移動端開發中急須要一個完善的Form表單組件尼?作過移動端開發的小夥伴們應該都清楚,一個完整的App項目中避免不了要有登陸註冊功能,用戶信息,密碼等一系列須要新用戶填寫信息的頁面,這些頁面的UI若是都是循序漸進的去繪製,實際上是作了不少無用功,由於大部分UI都長的差很少,就是有些文案類的略微不一樣,既然這樣,咱們將這些長的差很少的UI抽離成組件,在須要用到的地方,直接調用封裝好的組件,這樣極大的下降了編寫代碼量,大大的提升開發者的效率git
後期完成登陸註冊、身份認證等表單信息頁面的開發,咱們只須要一個簡單的配置文件便可搞定,沒必要每次相同的表單項都從新繪製一遍UI。對於哪些不常見的表單項,咱們能夠徹底使用自定義UI來搞定,這樣一來,咱們在平時開發中的80%的表單需求都能輕鬆的搞定了github
renderFields(fields) {
let fieldCount = fields.length ? fields.length : 0
return fields.map((field, index) => {
let isLastField = true
if (fieldCount === index + 1 || fields[index + 1].title !== undefined) {
isLastField = false
}
if (field.title !== undefined && field.show !== false) {
return this.renderGroupForm(field)
} else {
let {show, type, label, subLabel, subTitle, ...other} = field
let otherProps = {...other}
Object.keys(otherProps).map((key, index) => {
if (key.indexOf('on') === 0 || key === 'callback' || key === 'dataFunc' || key === 'view') {
otherProps[key] = this.props[otherProps[key]]
}
})
let isEditable = !this.props.readOnly && !this._isReadOnly(field.readOnly)
if (show !== false) {
if (this.fieldsType[type]) {
if (type === 'TextInput') {
return (
<View
key={index}
style={[styles.row, !isLastField ? {borderBottomWidth: 1, borderBottomColor: commonStyle.lineColor} : null]}
>
<View style={[styles.content, isLastField ? styles.lastLine : null]}>
{
label ?
<View style={styles.leftPanel}>
<View style={styles.leftTitle}>
<Text style={{fontSize: 15, color: commonStyle.textBlockColor}}>{label}</Text>
<Text style={{fontSize: 20, color: commonStyle.red}}>{subLabel}</Text>
</View>
{
subTitle ?
<View style={styles.subTitle}>
<Text style={{fontSize: 12, color: commonStyle.textGrayColor}}>{subTitle}</Text>
</View> : null
}
</View> : null
}
<View style={styles.inputContainer}>
<TextInput
style={styles.textInput}
{...otherProps}
placeholderTextColor={commonStyle.placeholderTextColor}
underlineColorAndroid={'transparent'}
editable={isEditable}
value={this.state[field.key] !== undefined && this.state[field.key] !== null && this.state[field.key].toString()}
onChangeText={value => {
this.state[field.key] = value
this.setState(this.state)
let _obj = {}
_obj[field.key] = value
this.props.onChange && this.props.onChange(_obj)
}}
/>
</View>
</View>
</View>
)
} else if (type === 'Button') {
return (
<View
key={index}
style={[styles.row, !isLastField ? {borderBottomWidth: 1, borderBottomColor: commonStyle.lineColor} : null]}>
<View
style={[styles.content, isLastField ? styles.lastLine : null, {justifyContent: commonStyle.center}]}>
<Button
{...field}
{...otherProps}>
{field.text}
</Button>
</View>
</View>
)
} else if (type === 'ButtonGroup') {
return (
<View
key={index}
style={[styles.row, !isLastField ? {borderBottomWidth: 1, borderBottomColor: commonStyle.lineColor} : null]}>
<View style={[styles.content, isLastField ? styles.lastLine : null]}>
{
label ?
<View style={styles.leftPanel}>
<View style={styles.leftTitle}>
<Text style={{fontSize: 15, color: commonStyle.textBlockColor}}>{label}</Text>
<Text style={{fontSize: 20, color: commonStyle.red}}>{subLabel}</Text>
</View>
{
subTitle ?
<View style={styles.subTitle}>
<Text style={{fontSize: 12, color: commonStyle.textGrayColor}}>{subTitle}</Text>
</View> : null
}
</View> : null
}
<View style={{flex: 1, height: 49, flexDirection: commonStyle.row, alignItems: commonStyle.center, justifyContent: 'flex-end', marginRight: 10}}>
{
field.items.map((item, index) => {
let _cloneBtn = deepClone(item)
Object.keys(_cloneBtn).map((key, index) => {
if (key.indexOf('on') === 0) {
_cloneBtn[key] = this.props[_cloneBtn[key]]
}
})
if (typeof _cloneBtn.selected === 'boolean') {
return (
<Button
key={index}
style={[_cloneBtn.style, _cloneBtn.selected ? _cloneBtn.selectedStyle : null]}
textStyle={[_cloneBtn.textStyle, _cloneBtn.selected ? _cloneBtn.textSelectedStyle : null]}
{..._cloneBtn}
>
{_cloneBtn.text}
</Button>
)
} else {
return (
<Button
key={index}
style={[_cloneBtn.style, _cloneBtn.selected && _cloneBtn.selected() ? _cloneBtn.selectedStyle : null]}
textStyle={[_cloneBtn.textStyle, _cloneBtn.selected && _cloneBtn.selected() ? _cloneBtn.textSelectedStyle : null]}
>
{_cloneBtn.text}
</Button>
)
}
})
}
</View>
</View>
</View>
)
} else if (type === 'Switch') {
return (
<View
key={index}
style={[styles.row, !isLastField ? {borderBottomWidth: 1, borderBottomColor: commonStyle.lineColor} : null]}
>
<View style={[styles.content, isLastField ? styles.lastLine : null]}>
{
label ?
<View style={styles.leftPanel}>
<View style={styles.leftTitle}>
<Text style={{fontSize: 15, color: commonStyle.textBlockColor}}>{label}</Text>
<Text style={{fontSize: 20, color: commonStyle.red}}>{subLabel}</Text>
</View>
{
subTitle ?
<View style={styles.subTitle}>
<Text style={{fontSize: 12, color: commonStyle.textGrayColor}}>{subTitle}</Text>
</View> : null
}
</View> : null
}
<View style={styles.switch}>
<Switch
disabled={!isEditable}
value={this.state[field.key] !== undefined && this.state[field.key] !== null && this.state[field.key]}
onValueChange={value => {
this.state[field.key] = value
this.setState(this.state)
let _obj = {}
_obj[field.key] = value
this.props.onChange && this.props.onChange(_obj)
}}
/>
</View>
</View>
</View>
)
} else if (type === 'View') {
return (
<View key={index}
style={[styles.row, !isLastField ? {borderBottomWidth: 1, borderBottomColor: commonStyle.lineColor} : null]}>
<View
key={index}
style={[styles.content, isLastField ? styles.lastLine : null]}>
{
label ?
<View style={styles.leftPanel}>
<View style={styles.leftTitle}>
<Text style={{fontSize: 15, color: commonStyle.textBlockColor}}>{label}</Text>
<Text style={{fontSize: 20, color: commonStyle.red}}>{subLabel}</Text>
</View>
{
subTitle ?
<View style={styles.subTitle}>
<Text style={{fontSize: 12, color: commonStyle.textGrayColor}}>{subTitle}</Text>
</View> : null
}
</View> : null
}
<View
ref={'customView'}
style={styles.view}
{...field}
{...otherProps}
>
{otherProps.view}
</View>
</View>
</View>
)
} else if (type === 'TextArea') {
let Comp = this.fieldsType[type]
return (
<View key={index}
style={[styles.row, !isLastField ? {borderBottomWidth: 1, borderBottomColor: commonStyle.lineColor} : null]}>
<View
key={index}
style={[styles.content, isLastField ? styles.lastLine : null]}>
{
label ?
<View style={styles.leftPanel}>
<View style={styles.leftTitle}>
<Text style={{fontSize: 15, color: commonStyle.textBlockColor}}>{label}</Text>
<Text style={{fontSize: 20, color: commonStyle.red}}>{subLabel}</Text>
</View>
{
subTitle ?
<View style={styles.subTitle}>
<Text style={{fontSize: 12, color: commonStyle.textGrayColor}}>{subTitle}</Text>
</View> : null
}
</View> : null
}
<Comp
ref={(ref) => this._component[field.key] = ref}
name={field.key}
value={this.state}
editable={isEditable}
{...field}
{...otherProps}
onChange={this.props.onChange && this.props.onChange()}
/>
</View>
</View>
)
} else {
let Comp = this.fieldsType[type]
return (
<View key={index}
style={[styles.row, !isLastField ? {borderBottomWidth: 1, borderBottomColor: commonStyle.lineColor} : null]}>
<View
key={index}
style={[styles.content, isLastField ? styles.lastLine : null]}>
{
label ?
<View style={styles.leftPanel}>
<View style={styles.leftTitle}>
<Text style={{fontSize: 15, color: commonStyle.textBlockColor}}>{label}</Text>
<Text style={{fontSize: 20, color: commonStyle.red}}>{subLabel}</Text>
</View>
{
subTitle ?
<View style={styles.subTitle}>
<Text style={{fontSize: 12, color: commonStyle.textGrayColor}}>{subTitle}</Text>
</View> : null
}
</View> : null
}
<View style={{flex: 1}}>
<Comp
ref={(ref) => this._component[field.key] = ref}
name={field.key}
value={this.state}
editable={isEditable}
{...field}
{...otherProps}
descValue={field.name}
onChange={this.props.onChange && this.props.onChange()}
/>
</View>
</View>
</View>
)
}
} else {
return (
<View key={index}
style={[styles.row, !isLastField ? {borderBottomWidth: 1, borderBottomColor: commonStyle.lineColor} : null]}>
<View
key={index}
style={[styles.content, isLastField ? styles.lastLine : null]}>
{
label ?
<View style={styles.leftPanel}>
<View style={styles.leftTitle}>
<Text style={{fontSize: 15, color: commonStyle.textBlockColor}}>{label}</Text>
<Text style={{fontSize: 20, color: commonStyle.red}}>{subLabel}</Text>
</View>
{
subTitle ?
<View style={styles.subTitle}>
<Text style={{fontSize: 12, color: commonStyle.textGrayColor}}>{subTitle}</Text>
</View> : null
}
</View> : null
}
<View style={{ flex: 1, height: 49 }}>
<CustomAction
type={type}
ref={(ref) => this._component[field.key] = ref}
name={field.key} value={this.state}
{...field}
{...otherProps}
editable={isEditable}
onChange={this.props.onChange}
descValue={field.name}
/>
</View>
</View>
</View>
)
}
}
}
})
}
複製代碼