Cascader


Install

  1. npm install beeshell

Usage

  1. import { Cascader } from 'beeshell';

示例

1. 一次性输入数据, 默认选中

image

2. 异步加载数据

image

3. 异步加载数据, 并选中, 自定义样式 例子4

image

CascaderItem 数据结构

  1. {
  2. label: '甜点饮品',
  3. value: 19, // 可以是 string 或者 int
  4. children: [
  5. { label: '甜品', value: 167 },
  6. { label: '咖啡', value: 168 }
  7. ],
  8. }
  • 可以通过 structKeys 配置键值对应. [label, value, children] 一一对应, 每一项都必填

Usage

1. React.Element

Cascader 是一个 React.Element 对象

2. Cascader 两种数据源

  • options 一次性导入模式, 可以配合 assignedOption 一起使用
  • onSyncData 异步请求模式, 也配合 assignedOption 一起使用

3. 一次性输入数据

  1. // constructor
  2. this.state = {
  3. options:[
  4. {
  5. label: '甜点饮品',
  6. value: 19,
  7. children: [
  8. { label: '甜品', value: 167 },
  9. { label: '咖啡', value: 168 },
  10. { label: 'icecream', value: 169 },
  11. ],
  12. },
  13. {
  14. label: '美食',
  15. value: 22,
  16. children: [
  17. {
  18. label: '火锅',
  19. value: 221,
  20. children: [
  21. { label: '四川火锅', value: 500 },
  22. { label: '云南火锅', value: 501 },
  23. { label: '羊蝎子火锅', value: 502 },
  24. ],
  25. },
  26. {
  27. label: '面',
  28. value: 112,
  29. children: [
  30. { label: '重庆小面', value: 600 },
  31. { label: '山西刀削面', value: 701 },
  32. ],
  33. },
  34. ],
  35. }
  36. ],
  37. assignedOption: [22, 112, 600]; // 默认选中
  38. }
  39. // handle
  40. handleConfirm(selectedChain){
  41. const content = selectedChain.map(item => item.label).join('/');
  42. }
  43. // render
  44. <Cascader
  45. options={this.state.options}
  46. assignedOption={this.state.assignedOption}
  47. onConfirm={this.handleConfirm.bind(this)}
  48. />

4. 异步请求数据, 也支持 assignedOption

  1. // 随机两位字符
  2. randomStr(length) {
  3. let text = '';
  4. const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  5. for (let i = 0; i < length; i++) {
  6. text += possible.charAt(Math.floor(Math.random() * possible.length));
  7. }
  8. return text;
  9. }
  10. /**
  11. * 异步请求 返回结果必须是个promise 对象
  12. * @param {*} option 一个选中的项目 {level}
  13. */
  14. syncLoadData(option) {
  15. const result = [];
  16. return new Promise((resolve, reject) => {
  17. // 这里做多返回3级菜单
  18. if (option.level < 3 && option.label !== '全部') {
  19. const nextLevel = option.level + 1;
  20. for (let index = 1; index < 10; index++) {
  21. result.push({
  22. name: `Level${nextLevel}-${index}-${this.randomStr(2)}`,
  23. value: 10 * nextLevel + index,
  24. });
  25. }
  26. setTimeout(() => {
  27. resolve(result);
  28. }, 200);
  29. } else {
  30. setTimeout(() => {
  31. reject();
  32. }, 200);
  33. }
  34. });
  35. }
  36. // render
  37. <Cascader
  38. style={{ flex: 1 }}
  39. onConfirm={this.handleConfirm.bind(this)}
  40. onChange={this.handleChange.bind(this)}
  41. itemSelectedStyle={{ color: 'green', backgroundColor: 'lightgreen' }}
  42. flexCols={[2, 1, 1]}
  43. structKeys={['name', 'value', 'child']}
  44. onSyncData={this.syncLoadData.bind(this)}
  45. assignedOption={[11,22,33]}
  46. />

5. 样式自定义

  1. // constructor
  2. this.state = {
  3. options:[
  4. {
  5. name: '甜点饮品',
  6. val: 19,
  7. child: [
  8. { name: '甜品', val: 167 },
  9. { name: '咖啡', val: 168 },
  10. { name: 'icecream', val: 169 },
  11. ],
  12. },
  13. {
  14. name: '美食',
  15. val: 22,
  16. child: [
  17. {
  18. name: '火锅',
  19. val: 221,
  20. child: [
  21. { name: '四川火锅', val: 500 },
  22. { name: '云南火锅', val: 501 },
  23. { name: '羊蝎子火锅', val: 502 },
  24. ],
  25. },
  26. {
  27. name: '面',
  28. val: 112,
  29. child: [
  30. { name: '重庆小面', val: 600 },
  31. { name: '山西刀削面', val: 701 },
  32. ],
  33. },
  34. ],
  35. },
  36. ],
  37. assignedOption: [22, 112, 701]; // 默认选中
  38. }
  39. // handle
  40. handleConfirm(selectedChain){
  41. const content = selectedChain.map(item => item.label).join('/');
  42. }
  43. // render
  44. // structKeys 键值对应 按照, label, value, children 一一对照
  45. <Cascader
  46. style={{ height: 300 }}
  47. options={this.state.options}
  48. assignedOption={this.state.assignedOption}
  49. onConfirm={this.handleConfirm.bind(this)}
  50. onChange={this.handleChange.bind(this)}
  51. itemSelectedStyle={{ color: 'blue', backgroundColor: 'lightyellow' }}
  52. flexCols={[2, 2, 1]}
  53. structKeys={['name', 'val', 'child']}
  54. />

Cascader 级联菜单 Attributes

参数 说明 类型 默认值 可选值
options 树形结构, 数据结构见上面 array [CascaderItem] 可选
assignedOption 默认选中的数组值 array[value] undefined 可选
onSyncData 异步请求的函数, 返回值必须是一个Promise,入参是一个选择项 {label,value,level} 对象 Promise
flexCols 各列的相对宽度, 长度要和最大列数一致, 支持默认选中, 异步请求时支持 array[int] 可选
structKeys CascaderItem key值对应, 适配不同的结构体, 异步请求时也支持 [‘label’,’value’,’children’] true 可选
itemStyle 选择项的样式 ReactNative.style 可选
itemSelectedStyle 选择项选中后的样式 ReactNative.style 可选

注意

  • onSyncData 和 options 异步数据和一次性数据不同时使用
  • assignedOption 同时支持 options,和 onSyncData 两种方式
  • assignedOption 最后一列可以是 -1, 这样只打开而不会选中
  • structKeys 键值对应 按照, [label, value, children] 一一对应, 每一项都必填
  • flexCols 如果不设置,就会按照当前列数自动均分. onSyncData 和 options 两种模式可以使用

Cascader 级联菜单 Events

事件名称 说明 回调参数
onConfirm 最终选中的值, 没有children的时候触发 array[CascaderItem]
onChange 每次点击时触发, 有children的时候触发 array[CascaderItem]

注意

  • onConfirm 和 onChange 的触发条件互斥

feature

  • 列相对布局, 如果设置那么按照设置的来, 默认按列数动态调整
  • 默认插入全部选项 方便全选

flexCols

options, assignedOption 一起使用
onSyncData 异步请求,支持异步请求并且默认选中

structKeys值[label, value, children]

TODO

  • 多列
  • 默认选择, 自动打开
  • 多列默认选择, 参考casader
  • 是否联动, 以及对应的数据格式
  • 不同列单独的数据请求, promise 等, 然后请求下一页面
  • 异步数据接口,暂时不做默认选中?
  • itemStyle itemSelectStyle
  • 列相对布局, 设置过才起作用
  • 数据格式key值转换
  • onChange
  • 减少 render 次数
  • Android 兼容性
  • typescript 兼容