动态菜单和动态路由的 antd pro

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import React, { Component } from 'react';
  2. import classNames from 'classnames';
  3. import { Tag, Icon } from 'antd';
  4. import styles from './index.less';
  5. const { CheckableTag } = Tag;
  6. const TagSelectOption = ({ children, checked, onChange, value }) => (
  7. <CheckableTag checked={checked} key={value} onChange={state => onChange(value, state)}>
  8. {children}
  9. </CheckableTag>
  10. );
  11. TagSelectOption.isTagSelectOption = true;
  12. class TagSelect extends Component {
  13. state = {
  14. expand: false,
  15. value: this.props.value || this.props.defaultValue || [],
  16. };
  17. componentWillReceiveProps(nextProps) {
  18. if ('value' in nextProps && nextProps.value) {
  19. this.setState({ value: nextProps.value });
  20. }
  21. }
  22. onChange = value => {
  23. const { onChange } = this.props;
  24. if (!('value' in this.props)) {
  25. this.setState({ value });
  26. }
  27. if (onChange) {
  28. onChange(value);
  29. }
  30. };
  31. onSelectAll = checked => {
  32. let checkedTags = [];
  33. if (checked) {
  34. checkedTags = this.getAllTags();
  35. }
  36. this.onChange(checkedTags);
  37. };
  38. getAllTags() {
  39. let { children } = this.props;
  40. children = React.Children.toArray(children);
  41. const checkedTags = children
  42. .filter(child => this.isTagSelectOption(child))
  43. .map(child => child.props.value);
  44. return checkedTags || [];
  45. }
  46. handleTagChange = (value, checked) => {
  47. const checkedTags = [...this.state.value];
  48. const index = checkedTags.indexOf(value);
  49. if (checked && index === -1) {
  50. checkedTags.push(value);
  51. } else if (!checked && index > -1) {
  52. checkedTags.splice(index, 1);
  53. }
  54. this.onChange(checkedTags);
  55. };
  56. handleExpand = () => {
  57. this.setState({
  58. expand: !this.state.expand,
  59. });
  60. };
  61. isTagSelectOption = node => {
  62. return (
  63. node &&
  64. node.type &&
  65. (node.type.isTagSelectOption || node.type.displayName === 'TagSelectOption')
  66. );
  67. };
  68. render() {
  69. const { value, expand } = this.state;
  70. const { children, className, style, expandable } = this.props;
  71. const checkedAll = this.getAllTags().length === value.length;
  72. const cls = classNames(styles.tagSelect, className, {
  73. [styles.hasExpandTag]: expandable,
  74. [styles.expanded]: expand,
  75. });
  76. return (
  77. <div className={cls} style={style}>
  78. <CheckableTag checked={checkedAll} key="tag-select-__all__" onChange={this.onSelectAll}>
  79. 全部
  80. </CheckableTag>
  81. {value &&
  82. React.Children.map(children, child => {
  83. if (this.isTagSelectOption(child)) {
  84. return React.cloneElement(child, {
  85. key: `tag-select-${child.props.value}`,
  86. value: child.props.value,
  87. checked: value.indexOf(child.props.value) > -1,
  88. onChange: this.handleTagChange,
  89. });
  90. }
  91. return child;
  92. })}
  93. {expandable && (
  94. <a className={styles.trigger} onClick={this.handleExpand}>
  95. {expand ? '收起' : '展开'} <Icon type={expand ? 'up' : 'down'} />
  96. </a>
  97. )}
  98. </div>
  99. );
  100. }
  101. }
  102. TagSelect.Option = TagSelectOption;
  103. export default TagSelect;