|
2#
楼主 |
发表于 2018-6-11 17:26:43
|
只看该作者
复制代码
- <p> 1 import React, { Component, PropTypes } from 'react'</p><p> 2 import { connect } from 'react-redux'</p><p> 3 import Cascader from 'antd/lib/cascader'</p><p> 4 import Button from 'antd/lib/button'</p><p> 5 import message from 'antd/lib/message'</p><p> 6 import ajax from '../../utils/service'</p><p> 7 import * as inputActions from '../../actions/input'</p><p> 8 </p><p> 9 let province = [</p><p> 10 { value: 2, label: "北京", isLeaf: false },</p><p> 11 { value: 3, label: "安徽", isLeaf: false },</p><p> 12 { value: 4, label: "福建", isLeaf: false },</p><p> 13 { value: 5, label: "甘肃", isLeaf: false },</p><p> 14 { value: 6, label: "广东", isLeaf: false },</p><p> 15 { value: 7, label: "广西", isLeaf: false },</p><p> 16 { value: 8, label: "贵州", isLeaf: false },</p><p> 17 { value: 9, label: "海南", isLeaf: false },</p><p> 18 { value: 10, label: "河北", isLeaf: false },</p><p> 19 { value: 11, label: "河南", isLeaf: false },</p><p> 20 { value: 12, label: "黑龙江", isLeaf: false },</p><p> 21 { value: 13, label: "湖北", isLeaf: false },</p><p> 22 { value: 14, label: "湖南", isLeaf: false },</p><p> 23 { value: 15, label: "吉林", isLeaf: false },</p><p> 24 { value: 16, label: "江苏", isLeaf: false },</p><p> 25 { value: 17, label: "江西", isLeaf: false },</p><p> 26 { value: 18, label: "辽宁", isLeaf: false },</p><p> 27 { value: 19, label: "内蒙古", isLeaf: false },</p><p> 28 { value: 20, label: "宁夏", isLeaf: false },</p><p> 29 { value: 21, label: "青海", isLeaf: false },</p><p> 30 { value: 22, label: "山东", isLeaf: false },</p><p> 31 { value: 23, label: "山西", isLeaf: false },</p><p> 32 { value: 24, label: "陕西", isLeaf: false },</p><p> 33 { value: 25, label: "上海", isLeaf: false },</p><p> 34 { value: 26, label: "四川", isLeaf: false },</p><p> 35 { value: 27, label: "天津", isLeaf: false },</p><p> 36 { value: 28, label: "西藏", isLeaf: false },</p><p> 37 { value: 29, label: "新疆", isLeaf: false },</p><p> 38 { value: 30, label: "云南", isLeaf: false },</p><p> 39 { value: 31, label: "浙江", isLeaf: false },</p><p> 40 { value: 32, label: "重庆", isLeaf: false },</p><p> 41 { value: 33, label: "香港", isLeaf: false },</p><p> 42 { value: 34, label: "澳门", isLeaf: false },</p><p> 43 { value: 35, label: "台湾", isLeaf: false }</p><p> 44 ];</p><p> 45 </p><p> 46 let options = province</p><p> 47 </p><p> 48 class Location extends Component {</p><p> 49 constructor(props) {</p><p> 50 super(props);</p><p> 51 </p><p> 52 }</p><p> 53 state = {</p><p> 54 options: options,</p><p> 55 inputValue: '',</p><p> 56 }</p><p> 57 </p><p> 58 componentWillMount(){</p><p> 59 const {hideLoading} = this.props;</p><p> 60 setTimeout(() => { hideLoading()}, 1000)</p><p> 61 }</p><p> 62 </p><p> 63 _onChange = (value, selectedOptions) => {</p><p> 64 console.log(value);</p><p> 65 this.setState({</p><p> 66 inputValue: selectedOptions.map(o=>o.label).join(', ')</p><p> 67 });</p><p> 68 const onChange = this.props.onChange;</p><p> 69 </p><p> 70 if (onChange) {</p><p> 71 onChange({...value});</p><p> 72 }</p><p> 73 }</p><p> 74 </p><p> 75 _loadData = (selectedOptions) => {</p><p> 76 const targetOption = selectedOptions[selectedOptions.length - 1];</p><p> 77 const id = targetOption.value;</p><p> 78 targetOption.loading = true;</p><p> 79 </p><p> 80 if (selectedOptions.length == '1') {</p><p> 81 // 点击省,获取市</p><p> 82 ajax.post(ajax.api.GETSERVICEAREA, { id: id, token: localStorage.token }).then(data => {</p><p> 83 if(data.status.code == '1'){</p><p> 84 targetOption.loading = false;</p><p> 85 targetOption.children = [];</p><p> 86 data.result.map((v, k)=>{</p><p> 87 // 拼出市</p><p> 88 targetOption.children.push({ </p><p> 89 value: v.id,</p><p> 90 label: v.name,</p><p> 91 isLeaf: false, </p><p> 92 });</p><p> 93 }); </p><p> 94 this.setState({</p><p> 95 options: [...this.state.options],</p><p> 96 });</p><p> 97 }</p><p> 98 });</p><p> 99 }else if (selectedOptions.length == '2') {</p><p>100 // 点击市,获取区</p><p>101 ajax.post(ajax.api.GETSERVICEAREA, { id: id, token: localStorage.token }).then(data => {</p><p>102 if(data.status.code == '1'){</p><p>103 targetOption.loading = false;</p><p>104 targetOption.children = [];</p><p>105 data.result.map((v, k)=>{</p><p>106 // 拼出区</p><p>107 targetOption.children.push({ </p><p>108 value: v.id,</p><p>109 label: v.name,</p><p>110 isLeaf: true, </p><p>111 });</p><p>112 }); </p><p>113 this.setState({</p><p>114 options: [...this.state.options],</p><p>115 });</p><p>116 }</p><p>117 });</p><p>118 }else { </p><p>119 targetOption.loading = false;</p><p>120 }</p><p>121 }</p><p>122 </p><p>123 _resetLocation = () => {</p><p>124 document.getElementsByClassName('ant-cascader-picker-clear')[0].click();</p><p>125 this.setState({</p><p>126 inputValue: '',</p><p>127 });</p><p>128 }</p><p>129 </p><p>130 render() {</p><p>131 return (</p><p>132 <div></p><p>133 <Cascader</p><p>134 options={this.state.options}</p><p>135 loadData={this._loadData}</p><p>136 onChange={this._onChange}</p><p>137 changeOnSelect</p><p>138 placeholder=""</p><p>139 /></p><p>140 </div></p><p>141 )</p><p>142 }</p><p>143 }</p><p>144 </p><p>145 export default connect(state => ({</p><p>146 showLoginLayer: state.login.isShowLoginLayer</p><p>147 }), inputActions)(Location)</p>
复制代码
复制代码
其中要注意的地方很多,首先是初始值的设置。因为使用省市区组件,不能一次性拉取到所有的地区,
这样会十分消耗性能,造成不良的用户体验,正确的做法是在点击时获取下一级的地区信息,这样有针
对性的请求可以减少加载时间,那么问题来了,如何实现?
首先,使用 Cascader 的 api 中有 loadData 属性,可以定义数据的加载,同时,onChange 事件可以监
听到每一次的数据变化,但是使用 Cascader 有一个限制,便是第一级的数据需要在加载组件之前就定
义并获取到,否则无法进行下一级数据的加载,因此这里单独定义了所有了省的数据:
onChange 事件获取到当前选择的对象,并提供了两个参数,分别是选择的当前值(数组类型)和选择
的多级对象(当前选择的对象和当前对象下一级的数组对象)。
在获取到当前选中的对象后对值进行拼接处理并赋值给 inputValue (在组件框中显示的选中值),同时
设置onChange()方法,将值的变化情况通知给父组件(如 FormItem )
loadData()方法用于组件级联数据的加载,其参数就是 onChange()方法的第二个参数,在这里获
取到参数的最后一个对象(即当前点击的对象),通过判断参数的长度来识别当前要获取的数据的类型
(市还是区),获取到数据后生成组件要求的数据格式,最后将格式化的数据赋值给 option 就可以了。
最后,模拟了一个重置(清空)的功能,Cascader 值的清空有两点,一是选择框内容的清空,二是级
联数据的重置,内容的清空比较简单,直接将 inputValue 设置为空即可,而级联数据的重置不能将 o
ption 设置为空,这样会导致级联组件无法使用(下拉数据为空),为此使用了一个小技巧:
在组件的 api 属性中有一个allowClear 属性,默认是 true,即允许清空,其效果是当鼠标移到选择数据
后的级联表单上会出现一个 叉号的按钮,如下:
通过开发者工具可以获取到这个按钮的类名,那么之后的操作就简单了: 自定义一个重置(清空)按钮,
然后触发清空按钮的事件即可:
|
|