React三级联动组件代码优化20170327记
/** * @file 下拉框三级联动 * Created by wangzeqi . */ import React, {PropTypes} from 'common:widget/react/react.js'; import ReactDOM from 'common:widget/react/react-dom.js'; import Select from 'common:widget/form/select.jsx'; export default React.createClass({ // 数据类型,严谨模式 propTypes: { // option 数组 options: PropTypes.array.isRequired, // select change 事件回调 onChange: PropTypes.func, // select 的 id id: PropTypes.string, // 多个select的name, 数组格式 必须传递 name: PropTypes.array.isRequired, // select 的 label 显示的文字 label: PropTypes.string, // 自定义顶层元素的 class className: PropTypes.string, // 自定义顶层元素的样式 style: PropTypes.object, // 禁用全部 disabled: PropTypes.array, //默认值 数组 value: PropTypes.array, }, // 设置默认属性 getDefaultProps () { return { label: '', className: '', style: {}, id: '' + Date.now() + Math.random() + Date.now(), disabled: [false, false, false], value: ['' , '' , ''] } }, // 初始化设置 getInitialState () { return { value1:this.props.value[0], value2:this.props.value[1], value3:this.props.value[2], options1: [{ value: '0', text: '请选择' }], options2: [{ value: '0', text: '请选择' }], options3: [{ value: '0', text: '请选择' }], } }, render () { let self = this; let props = this.props; let id = props.id; let label = props.label; let name1 = props.name[0]; let name2 = props.name[1]; let name3 = props.name[2]; let disabled1 = props.disabled[0]; let disabled2 = props.disabled[1]; let disabled3 = props.disabled[2]; return ( <div id={id} className={'form-group ' + props.className} style={props.style}> <label htmlFor={id}>{label}</label> <div className="vertical-auto"> <Select name={name1} index='1' className="" label="" value={self.state.value1} disabled={disabled1} options={self.state.options1} onChange={self.onChange} /> <Select name={name2} index='2' className="" label="" value={self.state.value2} disabled={disabled2} options={self.state.options2} onChange={self.onChange} /> <Select name={name3} index='3' className="" label="" value={self.state.value3} disabled={disabled3} options={self.state.options3} onChange={self.onChange} /> </div> </div> ); }, selectChange (event) { var value = event.target.value; var index = event.target.dataset.index; this.state['value'+index] = value; this.forceUpdate(); }, //选项change事件 optionsChange (val, index) { var self = this; let arr = [{ value: '0', text: '请选择' }]; let options = this.props.options[index]; for (var item of options) { if (item.parent_code == val) { var obj = {}; obj.value = item.code; obj.text = item.name; arr.push(obj); } } if (index == 1) { this.setState({ options2: arr, options3: [{ value: '0', text: '请选择' }], value2:'0', value3:'0' }); } else if (index == 2) { this.setState({ options3: arr, value3:'0' }); } }, // 下拉框change事件 onChange (event) { var self = this; self.selectChange(event); var value = event.target.value; var index = event.target.dataset.index; if (index == '1') { self.optionsChange(value, 1); } else if (index == '2'){ self.optionsChange(value, 2); } }, // 初始化获取参数转换 getOption (index) { let arr = [{ value: '0', text: '请选择' }]; let options = this.props.options[index-1]; if(index == 1){ let options = this.props.options[0]; for (var item of options) { var obj = {}; obj.value = item.code; obj.text = item.name; arr.push(obj); } } else { let val = this.props.value[index-2]; for (var item of options) { if (item.parent_code == val) { var obj = {}; obj.value = item.code; obj.text = item.name; arr.push(obj); } } } this.state['options'+index] = arr; }, componentWillMount () { let self = this; self.getOption(1); if (this.props.value) { self.getOption(2); self.getOption(3); } } });
数据格式
getInitialState () { return { // 判断市是否展示 selectThree:[ [ { code:4, name:'辽宁省', parent_code:0 }, { code:1, name:'吉林省', parent_code:0 }, { code:2, name:'河北省', parent_code:0 }, ],[ { code:6, name:'沈阳', parent_code:4 }, { code:7, name:'辽阳', parent_code:4 }, { code:8, name:'长春', parent_code:1 }, { code:9, name:'吉林', parent_code:1 }, { code:10, name:'保定', parent_code:2 }, ],[ { code:15, name:'浑南', parent_code:6 }, { code:16, name:'铁西', parent_code:6 }, { code:21, name:'灯塔', parent_code:7 }, { code:17, name:'保定-A', parent_code:10 }, { code:18, name:'保定-B', parent_code:10 }, { code:19, name:'吉林-A', parent_code:9 }, { code:20, name:'长春-A', parent_code:8 }, ] ] } },
组件使用格式
<SelectThree name={['level1', 'level2', 'level3']} value={['4','6','16']} className="two" label="开户行省份" options={self.state.selectThree}/>
优化前代码
/** * @file 下拉框三级联动 * Created by wangzeqi . */ import React, {PropTypes} from 'common:widget/react/react.js'; import ReactDOM from 'common:widget/react/react-dom.js'; import Select from 'common:widget/form/select.jsx'; export default React.createClass({ // 数据类型,严谨模式 propTypes: { // option 数组 options: PropTypes.array.isRequired, // select change 事件回调 onChange: PropTypes.func, // select 的 id id: PropTypes.string, // 多个select的name, 数组格式 必须传递 name: PropTypes.array.isRequired, // select 的 label 显示的文字 label: PropTypes.string, // 自定义顶层元素的 class className: PropTypes.string, // 自定义顶层元素的样式 style: PropTypes.object, // 禁用全部 disabled: PropTypes.array, //默认值 数组 value: PropTypes.array, }, // 设置默认属性 getDefaultProps () { return { label: '', className: '', style: {}, id: '' + Date.now() + Math.random() + Date.now(), disabled: [false, false, false], value: ['' , '' , ''] } }, // 初始化设置 getInitialState () { return { value1:this.props.value[0], value2:this.props.value[1], value3:this.props.value[2], options1: [{ value: '0', text: '请选择' }], options2: [{ value: '0', text: '请选择' }], options3: [{ value: '0', text: '请选择' }], } }, render () { console.log(this.props); let self = this; let props = this.props; let id = props.id; let label = props.label; let name1 = props.name[0]; let name2 = props.name[1]; let name3 = props.name[2]; let value1 = props.value? props.value[0] : ''; let value2 = props.value? props.value[0] : ''; let value3 = props.value? props.value[0] : ''; let disabled1 = props.disabled[0]; let disabled2 = props.disabled[1]; let disabled3 = props.disabled[2]; return ( <div id={id} className={'form-group ' + props.className} style={props.style}> <label htmlFor={id}>{label}</label> <div className="vertical-auto"> <Select name={name1} index='1' className="" label="" defaultValue={self.state.value1} disabled={disabled1} options={self.state.options1} onChange={self.onChange} /> <Select name={name2} index='2' className="" label="" defaultValue={self.state.value2} disabled={disabled2} options={self.state.options2} onChange={self.onChange} /> <Select name={name3} index='3' className="" label="" defaultValue={self.state.value3} disabled={disabled3} options={self.state.options3}/> </div> </div> ); }, selectChange (event) { var value = event.target.value; var index = event.target.dataset.index; this.state['value'+index] = value; this.forceUpdate(); }, options2Change (val) { let arr = [{ value: '0', text: '请选择' }]; let options = this.props.options[2]; for (var item of options) { if (item.parent_code == val) { var obj = {}; obj.value = item.code; obj.text = item.name; arr.push(obj); } } this.setState({ options3: arr, value3:'' }); }, options1Change (val) { var self = this; let arr = [{ value: '0', text: '请选择' }]; let options = this.props.options[1]; for (var item of options) { if (item.parent_code == val) { var obj = {}; obj.value = item.code; obj.text = item.name; arr.push(obj); } } this.setState({ options2: arr, options3: [{ value: '0', text: '请选择' }], value2:'', value3:'' }); // self.options2Change(arr[0].value); }, onChange (event) { var self = this; // self.selectChange(event); var value = event.target.value; var index = event.target.dataset.index; if (index == '1') { self.options1Change(value); } else if (index == '2'){ self.options2Change(value); } }, getData () { return ReactDOM.findDOMNode(this.refs.select).value; }, componentWillMount () { // 格式转换 数据初始化展示 let arr = [{ value: '0', text: '请选择' }]; let options = this.props.options[0]; for (var item of options) { var obj = {}; obj.value = item.code; obj.text = item.name; arr.push(obj); } this.state.options1 = arr; let val; if (this.props.value) { val = this.props.value[0]; arr = []; options = this.props.options[1]; for (var item of options) { if (item.parent_code == val) { var obj = {}; obj.value = item.code; obj.text = item.name; arr.push(obj); } } this.state.options2 = arr; val = this.props.value[1]; arr = []; options = this.props.options[2]; for (var item of options) { if (item.parent_code == val) { var obj = {}; obj.value = item.code; obj.text = item.name; arr.push(obj); } } this.state.options3 = arr; } } });