• Cascader 级联选择

    级联选择框。

    何时使用

    代码演示

    省市区级联。
    expand code expand code
    import { Cascader } from 'choerodon-ui';
    
    const options = [{
      value: 'zhejiang',
      label: 'Zhejiang',
      children: [{
        value: 'hangzhou',
        label: 'Hangzhou',
        children: [{
          value: 'xihu',
          label: 'West Lake',
        }],
      }],
    }, {
      value: 'jiangsu',
      label: 'Jiangsu',
      children: [{
        value: 'nanjing',
        label: 'Nanjing',
        children: [{
          value: 'zhonghuamen',
          label: 'Zhong Hua Men',
        }],
      }],
    }];
    
    function onChange(value) {
      console.log(value);
    }
    
    ReactDOM.render(
      <Cascader label="cascader" options={options} onChange={onChange} placeholder="Please select" />,
      mountNode);
    
    切换按钮和结果分开。
    expand code expand code
    import { Cascader } from 'choerodon-ui';
    
    const options = [{
      value: 'zhejiang',
      label: 'Zhejiang',
      children: [{
        value: 'hangzhou',
        label: 'Hangzhou',
      }],
    }, {
      value: 'jiangsu',
      label: 'Jiangsu',
      children: [{
        value: 'nanjing',
        label: 'Nanjing',
      }],
    }];
    
    class CitySwitcher extends React.Component {
      state = {
        text: 'Unselect',
      };
    
      onChange = (value, selectedOptions) => {
        this.setState({
          text: selectedOptions.map(o => o.label).join(', '),
        });
      }
    
      render() {
        return (
          <span>
            {this.state.text}
            &nbsp;
            <Cascader options={options} onChange={this.onChange}>
              <a href="#">Change city</a>
            </Cascader>
          </span>
        );
      }
    }
    
    ReactDOM.render(<CitySwitcher />, mountNode);
    
    通过指定 options 里的 disabled 字段。
    expand code expand code
    import { Cascader } from 'choerodon-ui';
    
    const options = [{
      value: 'zhejiang',
      label: 'Zhejiang',
      children: [{
        value: 'hangzhou',
        label: 'Hangzhou',
        children: [{
          value: 'xihu',
          label: 'West Lake',
        }],
      }],
    }, {
      value: 'jiangsu',
      label: 'Jiangsu',
      disabled: true,
      children: [{
        value: 'nanjing',
        label: 'Nanjing',
        children: [{
          value: 'zhonghuamen',
          label: 'Zhong Hua Men',
        }],
      }],
    }];
    
    function onChange(value) {
      console.log(value);
    }
    
    ReactDOM.render(
      <Cascader options={options} onChange={onChange} />,
      mountNode);
    
    不同大小的级联选择器。
    expand code expand code
    import { Cascader } from 'choerodon-ui';
    
    const options = [{
      value: 'zhejiang',
      label: 'Zhejiang',
      children: [{
        value: 'hangzhou',
        label: 'Hangzhou',
        children: [{
          value: 'xihu',
          label: 'West Lake',
        }],
      }],
    }, {
      value: 'jiangsu',
      label: 'Jiangsu',
      children: [{
        value: 'nanjing',
        label: 'Nanjing',
        children: [{
          value: 'zhonghuamen',
          label: 'Zhong Hua Men',
        }],
      }],
    }];
    
    function onChange(value) {
      console.log(value);
    }
    
    ReactDOM.render(
      <div>
        <Cascader size="large" options={options} onChange={onChange} /><br /><br />
        <Cascader options={options} onChange={onChange} /><br /><br />
        <Cascader size="small" options={options} onChange={onChange} /><br /><br />
      </div>,
      mountNode);
    
    可以直接搜索选项并选择。
    expand code expand code
    import { Cascader } from 'choerodon-ui';
    
    const options = [{
      value: 'zhejiang',
      label: 'Zhejiang',
      children: [{
        value: 'hangzhou',
        label: 'Hangzhou',
        children: [{
          value: 'xihu',
          label: 'West Lake',
        }, {
          value: 'xiasha',
          label: 'Xia Sha',
          disabled: true,
        }],
      }],
    }, {
      value: 'jiangsu',
      label: 'Jiangsu',
      children: [{
        value: 'nanjing',
        label: 'Nanjing',
        children: [{
          value: 'zhonghuamen',
          label: 'Zhong Hua men',
        }],
      }],
    }];
    
    function onChange(value, selectedOptions) {
      console.log(value, selectedOptions);
    }
    
    function filter(inputValue, path) {
      return (path.some(option => (option.label).toLowerCase().indexOf(inputValue.toLowerCase()) > -1));
    }
    
    ReactDOM.render(
      <Cascader
        options={options}
        onChange={onChange}
        placeholder="Please select"
        showSearch={{ filter }}
      />,
      mountNode
    );
    
    默认值通过数组的方式指定。
    expand code expand code
    import { Cascader } from 'choerodon-ui';
    
    const options = [{
      value: 'zhejiang',
      label: 'Zhejiang',
      children: [{
        value: 'hangzhou',
        label: 'Hangzhou',
        children: [{
          value: 'xihu',
          label: 'West Lake',
        }],
      }],
    }, {
      value: 'jiangsu',
      label: 'Jiangsu',
      children: [{
        value: 'nanjing',
        label: 'Nanjing',
        children: [{
          value: 'zhonghuamen',
          label: 'Zhong Hua Men',
        }],
      }],
    }];
    
    function onChange(value) {
      console.log(value);
    }
    
    ReactDOM.render(
      <Cascader defaultValue={['zhejiang', 'hangzhou', 'xihu']} options={options} onChange={onChange} />,
      mountNode);
    
    通过移入展开下级菜单,点击完成选择。
    expand code expand code
    import { Cascader } from 'choerodon-ui';
    
    const options = [{
      value: 'zhejiang',
      label: 'Zhejiang',
      children: [{
        value: 'hangzhou',
        label: 'Hangzhou',
        children: [{
          value: 'xihu',
          label: 'West Lake',
        }],
      }],
    }, {
      value: 'jiangsu',
      label: 'Jiangsu',
      children: [{
        value: 'nanjing',
        label: 'Nanjing',
        children: [{
          value: 'zhonghuamen',
          label: 'Zhong Hua Men',
        }],
      }],
    }];
    
    function onChange(value) {
      console.log(value);
    }
    
    // Just show the latest item.
    function displayRender(label) {
      return label[label.length - 1];
    }
    
    ReactDOM.render(
      <Cascader
        options={options}
        expandTrigger="hover"
        displayRender={displayRender}
        onChange={onChange}
      />,
      mountNode);
    
    这种交互允许只选中父级选项。
    expand code expand code
    import { Cascader } from 'choerodon-ui';
    
    const options = [{
      value: 'zhejiang',
      label: 'Zhejiang',
      children: [{
        value: 'hangzhou',
        label: 'Hanzhou',
        children: [{
          value: 'xihu',
          label: 'West Lake',
        }],
      }],
    }, {
      value: 'jiangsu',
      label: 'Jiangsu',
      children: [{
        value: 'nanjing',
        label: 'Nanjing',
        children: [{
          value: 'zhonghuamen',
          label: 'Zhong Hua Men',
        }],
      }],
    }];
    
    function onChange(value) {
      console.log(value);
    }
    
    ReactDOM.render(
      <Cascader options={options} onChange={onChange} changeOnSelect />,
      mountNode);
    
    例如给最后一项加上邮编链接。
    expand code expand code
    import { Cascader } from 'choerodon-ui';
    
    const options = [{
      value: 'zhejiang',
      label: 'Zhejiang',
      children: [{
        value: 'hangzhou',
        label: 'Hangzhou',
        children: [{
          value: 'xihu',
          label: 'West Lake',
          code: 752100,
        }],
      }],
    }, {
      value: 'jiangsu',
      label: 'Jiangsu',
      children: [{
        value: 'nanjing',
        label: 'Nanjing',
        children: [{
          value: 'zhonghuamen',
          label: 'Zhong Hua Men',
          code: 453400,
        }],
      }],
    }];
    
    function handleAreaClick(e, label, option) {
      e.stopPropagation();
      console.log('clicked', label, option);
    }
    
    const displayRender = (labels, selectedOptions) => labels.map((label, i) => {
      const option = selectedOptions[i];
      if (i === labels.length - 1) {
        return (
          <span key={option.value}>
            {label} (<a onClick={e => handleAreaClick(e, label, option)}>{option.code}</a>)
          </span>
        );
      }
      return <span key={option.value}>{label} / </span>;
    });
    
    ReactDOM.render(
      <Cascader
        options={options}
        defaultValue={['zhejiang', 'hangzhou', 'xihu']}
        displayRender={displayRender}
        style={{ width: '100%' }}
      />,
      mountNode);
    

    使用 loadData 实现动态加载选项。

    注意:loadDatashowSearch 无法一起使用。

    expand code expand code
    import { Cascader } from 'choerodon-ui';
    
    const options = [{
      value: 'zhejiang',
      label: 'Zhejiang',
      isLeaf: false,
    }, {
      value: 'jiangsu',
      label: 'Jiangsu',
      isLeaf: false,
    }];
    
    class LazyOptions extends React.Component {
      state = {
        options,
      };
    
      onChange = (value, selectedOptions) => {
        console.log(value, selectedOptions);
      }
    
      loadData = (selectedOptions) => {
        const targetOption = selectedOptions[selectedOptions.length - 1];
        targetOption.loading = true;
    
        // load options lazily
        setTimeout(() => {
          targetOption.loading = false;
          targetOption.children = [{
            label: `${targetOption.label} Dynamic 1`,
            value: 'dynamic1',
          }, {
            label: `${targetOption.label} Dynamic 2`,
            value: 'dynamic2',
          }];
          this.setState({
            options: [...this.state.options],
          });
        }, 1000);
      }
    
      render() {
        return (
          <Cascader
            options={this.state.options}
            loadData={this.loadData}
            onChange={this.onChange}
            changeOnSelect
          />
        );
      }
    }
    
    ReactDOM.render(<LazyOptions />, mountNode);
    

    API

    <Cascader options={options} onChange={onChange} />
    
    参数 说明 类型 默认值
    allowClear 是否支持清除 boolean true
    autoFocus 自动获取焦点 boolean false
    changeOnSelect 当此项为 true 时,点选每级菜单选项值都会发生变化,具体见上面的演示 boolean false
    className 自定义类名 string -
    defaultValue 默认的选中项 string[] []
    disabled 禁用 boolean false
    displayRender 选择后展示的渲染函数 (label, selectedOptions) => ReactNode label => label.join(' / ')
    expandTrigger 次级菜单的展开方式,可选 ‘click’ 和 ‘hover’ string ‘click’
    getPopupContainer 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。示例 Function(triggerNode) () => document.body
    loadData 用于动态加载选项,无法与 showSearch 一起使用 (selectedOptions) => void -
    notFoundContent 当下拉列表为空时显示的内容 string ‘Not Found’
    options 可选项数据源 object -
    placeholder 输入框占位文本 string ‘请选择’
    popupClassName 自定义浮层类名 string -
    popupPlacement 浮层预设位置:bottomLeft bottomRight topLeft topRight Enum bottomLeft
    popupVisible 控制浮层显隐 boolean -
    showSearch 在选择框中显示搜索框 boolean false
    size 输入框大小,可选 large default small string default
    style 自定义样式 string -
    value 指定选中项 string[] -
    onChange 选择完成后的回调 (value, selectedOptions) => void -
    onPopupVisibleChange 显示/隐藏浮层的回调 (value) => void -

    showSearch 为对象时,其中的字段:

    参数 说明 类型 默认值
    filter 接收 inputValue path 两个参数,当 path 符合筛选条件时,应返回 true,反之则返回 false。 function(inputValue, path): boolean
    matchInputWidth 搜索结果列表是否与输入框同宽 boolean
    render 用于渲染 filter 后的选项 function(inputValue, path): ReactNode
    sort 用于排序 filter 后的选项 function(a, b, inputValue)

    方法

    名称 描述
    blur() 移除焦点
    focus() 获取焦点

    注意,如果需要获得中国省市区数据,可以参考 china-division