首先我们需要有一个数据结构,首先需要是一个数组,当然字段都可以自己定义,我这里没按照规范起名。
核心在于将数据整理好,字段梳理清楚,将state中用到的字段动态插入,提醒必填项也要动态遍历。
比如:
let stateOptions = [{
value: 'name',
title: '允许传送',
type: 'inp',
isrequird: true
}, {
value: 'age',
title: '允许请求',
type: 'sel',
isrequird: false
}, {
value: 'runing',
title: '允许递归',
type: 'inp',
isrequird: true
}]
value标识当前字段的key
title标识当前input或者select前面的名称
type标识是input还是select
isrequird标识当前是否是必填
这里只写这几项,这是我在写项目之前的一个小样。所以并没有考虑的很全面。
我们需要在页面挂载的时候,将变量动态的添加到状态机中:
componentDidMount() {
setTimeout(() => {
let stateOptions = [{
value: 'name',
title: '允许传送',
type: 'inp',
isrequird: true
}, {
value: 'age',
title: '允许请求',
type: 'sel',
isrequird: false
}, {
value: 'runing',
title: '允许递归',
type: 'inp',
isrequird: true
}]
//创建一个临时对象 添加属性方便
let newObkj = {}
//初始化在view层需要用到的变量 放置state中
stateOptions.map(i => {
// 到时候换成字段标识
if (i.value === 'age') {
newObkj[i.value] = []
} else {
newObkj[i.value] = ''
}
})
//使用解构赋值的形式直接将生成好的变量对象放置state中
this.setState({
// 解构到state中
...newObkj,
myOptionList: stateOptions
})
})
}
页面使用:
render() {
let { myOptionList, } = this.state
// 随机生成options 数组
const children = [];
for (let i = 10; i < 36; i++) {
children.push({ title: `${i.toString(36) + i}`, key: `${i.toString(36) + i}` });
}
// 必填标识 *
let isrequird = <a href="#!" style={{ color: '#ff7875', fontSize: '12px', marginTop: '8px', marginLeft: '8px' }}>*</a>
return (
<div className="context" >
<div className="search" >
<div className="search-input">
<p className="search-input-title">{'XX设置'}</p>
<div className="search-input-row" style={{ marginTop: '20px' }} style={{ flexDirection: "column" }}>
<span style={{ marginRight: '6%' }}></span>
<div style={{ textAlign: 'right', whiteSpace: 'nowrap', display: 'flex', flexDirection: "column", justifyContent: 'space-between' }}>
{
myOptionList.map((item, index) => {
return (
item.type === 'inp' ?
<div key={index} style={{ display: 'flex', marginBottom: '10px' }}>
<Input value={this.state[`${item.value}`]} title={`${item.title}`} onChange={(e) => this.inputName(`${item.value}`, e.target.value)} />
{item.isrequird ? isrequird : ''}
</div>
:
item.type === 'sel' ?
<div key={index} className="search-input-row-element" style={{ marginBottom: '10px', display: 'flex', marginLeft: '0px' }}>
<Select
title={`${item.title}:`}
showArrow={true}
mode="tags"
style={{}}
value={this.state[`${item.value}`]}
onChange={(e) => { this.inputName(`${item.value}`, e) }}
tokenSeparators={[',']}
options={children}
keyField="key"
valueField="key"
titleField="title"
dropdownMatchSelectWidth={true}
></Select>
{item.isrequird ? isrequird : ''}
</div>
: ''
)
})
}
</div>
</div >
</div>
</div>
<div className="device_search" style={{ marginLeft: "0px", marginBottom: '20px', marginTop: '20px', textAlign: "center" }}>
<Button Type="noIcon" title="测试按钮" onClick={() => this.bottomBtnClick('1')}></Button>
<span style={{ marginRight: '20px' }}></span>
<Button Type="noIcon" color="#E6A23C" title="返回" onClick={() => this.bottomBtnClick('2')}></Button>
</div>
</div>
)
}
上方使用三木运算判断标识显示input组件还是select组件,是否显示必填的标识。
动态生成了select中的options。
input和select输入获取值放置统一方法中:
// 输入框 输入
inputName = (type, e) => {
let tempData = {}
if (e.target) {
tempData[type] = e.target.value
} else {
tempData[type] = e
}
this.setState(tempData)
}
点击提交的时候动态遍历所有的必输项,没输入则提示:
bottomBtnClick = () => {
let { myOptionList } = this.state
// 动态遍历 必输项
// 提交前判断格式中是否有必填项
for (let key in myOptionList) {
if (myOptionList[key].isrequird) {
if (this.state[`${myOptionList[key].value}`] === '' || this.state[`${myOptionList[key].value}`].toString() === '[]') {
message.error(`请将${myOptionList[key].title}填写完整!`);
return false
}
}
}
console.log(this.state)
}
全部代码:里面所有的都是使用antd组件写的,所有只看思路就ok
import React from 'react'
import { message } from 'antd';
import { withRouter } from 'react-router-dom'
import Button from '../../component/Button';
import Select from '../../component/Select';
import Input from '../../component/Input';
class Options extends React.Component {
state = {
myOptionList: [],
}
componentDidMount() {
setTimeout(() => {
let stateOptions = [{
value: 'name',
title: '允许传送',
type: 'inp',
isrequird: true
}, {
value: 'age',
title: '允许请求',
type: 'sel',
isrequird: false
}, {
value: 'runing',
title: '允许递归',
type: 'inp',
isrequird: true
}]
let newObkj = {}
stateOptions.map(i => {
// 到时候换成字段标识
if (i.value === 'age') {
newObkj[i.value] = []
} else {
newObkj[i.value] = ''
}
})
this.setState({
// 解构到state中
...newObkj,
myOptionList: stateOptions
})
})
}
// 输入框 输入
inputName = (type, e) => {
let tempData = {}
if (e.target) {
tempData[type] = e.target.value
} else {
tempData[type] = e
}
this.setState(tempData)
}
bottomBtnClick = () => {
let { myOptionList } = this.state
// 动态遍历 必输项
// 提交前判断格式中是否有必填项
for (let key in myOptionList) {
if (myOptionList[key].isrequird) {
if (this.state[`${myOptionList[key].value}`] === '' || this.state[`${myOptionList[key].value}`].toString() === '[]') {
message.error(`请将${myOptionList[key].title}填写完整!`);
return false
}
}
}
console.log(this.state)
}
render() {
let { myOptionList, } = this.state
// 随机生成options 数组
const children = [];
for (let i = 10; i < 36; i++) {
children.push({ title: `${i.toString(36) + i}`, key: `${i.toString(36) + i}` });
}
// 必填标识 *
let isrequird = <a href="#!" style={{ color: '#ff7875', fontSize: '12px', marginTop: '8px', marginLeft: '8px' }}>*</a>
return (
<div className="context" >
<div className="search" >
<div className="search-input">
<p className="search-input-title">{'XX设置'}</p>
<div className="search-input-row" style={{ marginTop: '20px' }} style={{ flexDirection: "column" }}>
<span style={{ marginRight: '6%' }}></span>
<div style={{ textAlign: 'right', whiteSpace: 'nowrap', display: 'flex', flexDirection: "column", justifyContent: 'space-between' }}>
{
myOptionList.map((item, index) => {
return (
item.type === 'inp' ?
<div key={index} style={{ display: 'flex', marginBottom: '10px' }}>
<Input value={this.state[`${item.value}`]} title={`${item.title}`} onChange={(e) => this.inputName(`${item.value}`, e.target.value)} />
{item.isrequird ? isrequird : ''}
</div>
:
item.type === 'sel' ?
<div key={index} className="search-input-row-element" style={{ marginBottom: '10px', display: 'flex', marginLeft: '0px' }}>
<Select
title={`${item.title}:`}
showArrow={true}
mode="tags"
style={{}}
value={this.state[`${item.value}`]}
onChange={(e) => { this.inputName(`${item.value}`, e) }}
tokenSeparators={[',']}
options={children}
keyField="key"
valueField="key"
titleField="title"
dropdownMatchSelectWidth={true}
></Select>
{item.isrequird ? isrequird : ''}
</div>
: ''
)
})
}
</div>
</div >
</div>
</div>
<div className="device_search" style={{ marginLeft: "0px", marginBottom: '20px', marginTop: '20px', textAlign: "center" }}>
<Button Type="noIcon" title="测试按钮" onClick={() => this.bottomBtnClick('1')}></Button>
<span style={{ marginRight: '20px' }}></span>
<Button Type="noIcon" color="#E6A23C" title="返回" onClick={() => this.bottomBtnClick('2')}></Button>
</div>
</div>
)
}
}
export default withRouter(Options)