Picker 选择器

在一组预设数据中进行选择,e.g. 省市区选择。

规则

  • 尽量使用 Picker 来帮助用户完成输入,避免用户通过键盘直接输入。

  • DatePicker 是 Picker 的特定模式。

代码演示

基本

数据级联选择示例. (rc-form 文档)

  1. import { Picker, List, WhiteSpace } from 'antd-mobile';
  2. import { createForm } from 'rc-form';
  3. import arrayTreeFilter from 'array-tree-filter';
  4. import { district, provinceLite } from 'antd-mobile-demo-data';
  5. // 如果不是使用 List.Item 作为 children
  6. const CustomChildren = props => (
  7. <div
  8. onClick={props.onClick}
  9. style={{ backgroundColor: '#fff', paddingLeft: 15 }}
  10. >
  11. <div className="test" style={{ display: 'flex', height: '45px', lineHeight: '45px' }}>
  12. <div style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{props.children}</div>
  13. <div style={{ textAlign: 'right', color: '#888', marginRight: 15 }}>{props.extra}</div>
  14. </div>
  15. </div>
  16. );
  17. const seasons = [
  18. [
  19. {
  20. label: '2013',
  21. value: '2013',
  22. },
  23. {
  24. label: '2014',
  25. value: '2014',
  26. },
  27. ],
  28. [
  29. {
  30. label: '春',
  31. value: '春',
  32. },
  33. {
  34. label: '夏',
  35. value: '夏',
  36. },
  37. ],
  38. ];
  39. const colorStyle = {
  40. display: 'inline-block',
  41. verticalAlign: 'middle',
  42. width: '16px',
  43. height: '16px',
  44. marginRight: '10px',
  45. };
  46. const colors = [
  47. {
  48. label:
  49. (<div>
  50. <span
  51. style={{ ...colorStyle, backgroundColor: '#FF0000' }}
  52. />
  53. <span>红色</span>
  54. </div>),
  55. value: '#FF0000',
  56. },
  57. {
  58. label:
  59. (<div>
  60. <span
  61. style={{ ...colorStyle, backgroundColor: '#00FF00' }}
  62. />
  63. <span>绿色</span>
  64. </div>),
  65. value: '#00FF00',
  66. },
  67. {
  68. label:
  69. (<div>
  70. <span
  71. style={{ ...colorStyle, backgroundColor: '#0000FF' }}
  72. />
  73. <span>蓝色</span>
  74. </div>),
  75. value: '#0000FF',
  76. },
  77. ];
  78. class Test extends React.Component {
  79. state = {
  80. data: [],
  81. cols: 1,
  82. pickerValue: [],
  83. asyncValue: [],
  84. sValue: ['2013', '春'],
  85. visible: false,
  86. colorValue: ['#00FF00'],
  87. };
  88. onClick = () => {
  89. setTimeout(() => {
  90. this.setState({
  91. data: provinceLite,
  92. });
  93. }, 120);
  94. };
  95. onPickerChange = (val) => {
  96. console.log(val);
  97. let colNum = 1;
  98. const d = [...this.state.data];
  99. const asyncValue = [...val];
  100. if (val[0] === 'zj') {
  101. d.forEach((i) => {
  102. if (i.value === 'zj') {
  103. colNum = 2;
  104. if (!i.children) {
  105. i.children = [{
  106. value: 'zj-nb',
  107. label: '宁波',
  108. }, {
  109. value: 'zj-hz',
  110. label: '杭州',
  111. }];
  112. asyncValue.push('zj-nb');
  113. } else if (val[1] === 'zj-hz') {
  114. i.children.forEach((j) => {
  115. if (j.value === 'zj-hz') {
  116. j.children = [{
  117. value: 'zj-hz-xh',
  118. label: '西湖区',
  119. }];
  120. asyncValue.push('zj-hz-xh');
  121. }
  122. });
  123. colNum = 3;
  124. }
  125. }
  126. });
  127. } else {
  128. colNum = 1;
  129. }
  130. this.setState({
  131. data: d,
  132. cols: colNum,
  133. asyncValue,
  134. });
  135. };
  136. getSel() {
  137. const value = this.state.pickerValue;
  138. if (!value) {
  139. return '';
  140. }
  141. const treeChildren = arrayTreeFilter(district, (c, level) => c.value === value[level]);
  142. return treeChildren.map(v => v.label).join(',');
  143. }
  144. // setVal() {
  145. // this.props.form.setFieldsValue({
  146. // district: ['340000', '340800', '340822'],
  147. // });
  148. // },
  149. onChangeColor = (color) => {
  150. this.setState({
  151. colorValue: color,
  152. });
  153. };
  154. render() {
  155. const { getFieldProps } = this.props.form;
  156. return (<div>
  157. <WhiteSpace size="lg" />
  158. <List style={{ backgroundColor: 'white' }} className="picker-list">
  159. <Picker extra="请选择(可选)"
  160. data={district}
  161. title="Areas"
  162. {...getFieldProps('district', {
  163. initialValue: ['340000', '341500', '341502'],
  164. })}
  165. onOk={e => console.log('ok', e)}
  166. onDismiss={e => console.log('dismiss', e)}
  167. >
  168. <List.Item arrow="horizontal">Multiple & cascader</List.Item>
  169. </Picker>
  170. <Picker
  171. data={seasons}
  172. title="选择季节"
  173. cascade={false}
  174. extra="请选择(可选)"
  175. value={this.state.sValue}
  176. onChange={v => this.setState({ sValue: v })}
  177. onOk={v => this.setState({ sValue: v })}
  178. >
  179. <List.Item arrow="horizontal">Multiple</List.Item>
  180. </Picker>
  181. <Picker data={district} cols={1} {...getFieldProps('district3')} className="forss">
  182. <List.Item arrow="horizontal">Single</List.Item>
  183. </Picker>
  184. <Picker
  185. data={this.state.data}
  186. cols={this.state.cols}
  187. value={this.state.asyncValue}
  188. onPickerChange={this.onPickerChange}
  189. onOk={v => console.log(v)}
  190. >
  191. <List.Item arrow="horizontal" onClick={this.onClick}>Multiple & async</List.Item>
  192. </Picker>
  193. <Picker
  194. title="选择地区"
  195. extra="请选择(可选)"
  196. data={district}
  197. value={this.state.pickerValue}
  198. onChange={v => this.setState({ pickerValue: v })}
  199. onOk={v => this.setState({ pickerValue: v })}
  200. >
  201. <CustomChildren>Customized children</CustomChildren>
  202. </Picker>
  203. <Picker
  204. visible={this.state.visible}
  205. data={district}
  206. value={this.state.pickerValue}
  207. onChange={v => this.setState({ pickerValue: v })}
  208. onOk={() => this.setState({ visible: false })}
  209. onDismiss={() => this.setState({ visible: false })}
  210. >
  211. <List.Item extra={this.getSel()} onClick={() => this.setState({ visible: true })}>
  212. Visible state
  213. </List.Item>
  214. </Picker>
  215. <Picker
  216. data={colors}
  217. value={this.state.colorValue}
  218. cols={1}
  219. onChange={this.onChangeColor}
  220. >
  221. <List.Item arrow="horizontal">Complex Labels</List.Item>
  222. </Picker>
  223. </List>
  224. </div>);
  225. }
  226. }
  227. const TestWrapper = createForm()(Test);
  228. ReactDOM.render(<TestWrapper />, mountNode);
  1. .picker-list .am-list-item .am-list-line .am-list-extra {
  2. flex-basis: initial;
  3. }
  4. .test {
  5. position: relative;
  6. border-bottom: 0;
  7. }
  8. .test:after {
  9. content: '';
  10. position: absolute;
  11. background-color: #ddd;
  12. display: block;
  13. z-index: 1;
  14. top: auto;
  15. right: auto;
  16. bottom: 0;
  17. left: 0;
  18. width: 100%;
  19. height: 1PX;
  20. -webkit-transform-origin: 50% 100%;
  21. -ms-transform-origin: 50% 100%;
  22. transform-origin: 50% 100%;
  23. -webkit-transform: scaleY(0.5);
  24. -ms-transform: scaleY(0.5);
  25. transform: scaleY(0.5);
  26. }

Picker选择器 - 图1

API

属性说明类型默认值
data数据源Array<{value, label, children: Array}>-
value值, 格式是[value1, value2, value3], 对应数据源的相应级层valueArray-
format格式化选中目标的函数(labels: React.ReactNode[]): anyif label is string: (labels) => { return labels.join(',');} else: (labels) => { return labels;}
cols列数Number3
onChange选中后的回调,可使用rc-form(val): void-
onPickerChange每列数据选择变化后的回调函数(val): void-
onVisibleChange当显隐状态变化时回调函数(visible: bool): void-
itemStyle每列样式Object-
indicatorStyleindicator 样式Object-
children通常是 List.ItemObjectList.Item
okText选中的文案String确定
dismissText取消选中的文案String取消
onOk点击选中时执行的回调(val): void
onDismiss点击取消时执行的回调(): void
title大标题String-
extraPicker children 建议是 List.Item, 如果不是,需要是自定义组件(组件内需处理onClick/extra属性)String请选择
disabled是否不可用Booleanfalse
cascade是否联动Booleantrue