当我想要设计出这样的组件时,我面临的困难:

    1. <Statistic>
    2. <StatisticItem
    3. title="回答数"
    4. help="您的历史所有回答"
    5. data={983}
    6. value="+ 100%"
    7. // precision={2}
    8. // valueStyle={{ color: '#3f8600' }}
    9. valueprefix="日"
    10. valuesuffix={<Icon type="arrow-up" />}
    11. />
    12. <StatisticItem
    13. title="回答数"
    14. help="您的历史所有回答"
    15. data={983}
    16. value="+ 100%"
    17. // precision={2}
    18. // valueStyle={{ color: '#3f8600' }}
    19. valueprefix="日"
    20. valuesuffix={<Icon type="arrow-up" />}
    21. />
    22. </Statistic>

    1、StatisticItem作为Statistic的子组件,Statistic怎么读取到他的子组件的。
    Statistic包裹StatisticItem的主要作用是 作为父容器,提供均等分布局

    这里好像没啥作用?
    Statistic只负责提供外层的css即可?

    checkbox的设计:
    根据组件接口响应即可 无需管group的事( 如果group控制item的生成 ,那就直接绑定在group上

    1. <Checkbox defaultChecked={false} disabled />
    1. return (
    2. // eslint-disable-next-line jsx-a11y/label-has-associated-control
    3. <label
    4. className={classString}
    5. style={style}
    6. onMouseEnter={onMouseEnter}
    7. onMouseLeave={onMouseLeave}
    8. >
    9. <RcCheckbox
    10. {...checkboxProps}
    11. prefixCls={prefixCls}
    12. className={checkboxClass}
    13. ref={this.saveCheckbox}
    14. />
    15. {children !== undefined && <span>{children}</span>}
    16. </label>
    17. );

    对于 group:
    判断是否有children,
    如果有那么group就负责提供一下wrap的外壳
    如果没有,且options不为空 那么就由group控制生成checkbox
    image.png

    1. const options = [
    2. { label: 'Apple', value: 'Apple' },
    3. { label: 'Pear', value: 'Pear' },
    4. { label: 'Orange', value: 'Orange' },
    5. ];
    6. // GROUP 组件需要针对这种传入形式 帮用户生成 {}结果的数组item
    7. // const options = ['Apple','Pear','Orange'] 数组item为string 默认value、label等都一致
    8. <Checkbox.Group
    9. options={options}
    10. defaultValue={['Apple']}
    11. onChange={onChange}
    12. />
    13. ===>
    14. <Checkbox.Group style={{ width: '100%' }} onChange={onChange}>
    15. <Checkbox value="Apple">Apple</Checkbox>
    16. <Checkbox value="Pear">Pear</Checkbox>
    17. </Checkbox.Group>
    1. # 帮生成 {}结果的数组item
    2. getOptions() {
    3. const { options } = this.props;
    4. // https://github.com/Microsoft/TypeScript/issues/7960
    5. return (options as Array<CheckboxOptionType>).map(option => {
    6. if (typeof option === 'string') {
    7. return {
    8. label: option,
    9. value: option,
    10. } as CheckboxOptionType;
    11. }
    12. return option;
    13. });
    14. }

    children的处理:修改props.chilren 将新的render挂载在children上(有点意外,不过这样确实有道理

    1. option结构
    2. const options = [
    3. { label: 'Apple', value: 'Apple' },
    4. { label: 'Pear', value: 'Pear' },
    5. { label: 'Orange', value: 'Orange' },
    6. ];
    7. ===========
    8. let { children } = props;
    9. if (options && options.length > 0) {
    10. children = this.getOptions().map(option => (
    11. <Checkbox
    12. prefixCls={prefixCls}
    13. key={option.value.toString()}
    14. disabled={'disabled' in option ? option.disabled : props.disabled}
    15. value={option.value}
    16. checked={state.value.indexOf(option.value) !== -1}
    17. onChange={option.onChange}
    18. className={`${groupPrefixCls}-item`}
    19. >
    20. {option.label}
    21. </Checkbox>
    22. ));
    23. }
    24. const classString = classNames(groupPrefixCls, className);
    25. return (
    26. <div className={classString} style={style} {...domProps}>
    27. {children}
    28. </div
    29. );

    其中针对domProps的处理 使用了一些技巧
    const obj = {name:2333}
    const {name:newname} = obj; # 读取name属性 并使用新变量let newname = 2333;
    此时name并未被生成变量;

    1. const { prefixCls: customizePrefixCls, className, style, options, ...restProps } = props;
    2. const domProps = omit(restProps, ['children', 'defaultValue', 'value', 'onChange', 'disabled']);
    3. <div className={classString} style={style} {...domProps}>

    omit这里对 domProps进行了对象属性简化,只传递有用的属性给下一级,有用的属性是[]里包含的那些
    omit({ name: ‘Benjy’, age: 18 }, [ ‘name’ ]); // => { age: 18 }

    2、StatisticItem
    子组件 可以命名成 StatisticItem 也可以 Statistic.item
    怎么实现的,思量的,命令方式也是一种讲究吗
    image.pngimage.png

    ===>

    1. import Checkbox from './Checkbox';
    2. import Group from './Group';
    3. Checkbox.Group = Group;
    4. export default Checkbox;
    5. ===> const {}

    3、如果要支持 valueStyle 接口,组件使用者可以自己定义样式,组件内部应该怎么写呢?
    ===>
    1、classname的处理 [组件使用者传来的classname、根据接口变化的classname

    1. const { props } = this;
    2. const {className} = props;
    3. const classString = classNames(className, {
    4. [`${prefixCls}-wrapper`]: true,
    5. [`${prefixCls}-wrapper-checked`]: checkboxProps.checked,
    6. [`${prefixCls}-wrapper-disabled`]: checkboxProps.disabled,
    7. });
    1. 2style<br />直接承接组件定义的style
    1. <Checkbox.Group style={{ width: '100%' }} onChange={onChange}>
    2. # 内部
    3. const {style} = this.props;
    4. return (
    5. <div className={classString} style={style}>
    6. {children}
    7. </div>
    8. )

    4、是否可以提供一个更大的api挂载在Statistic上
    直接传入数组 然后渲染生成即可 item即可

    1. [
    2. {
    3. title: "回答数",
    4. help: "您的历史所有回答",
    5. data: 983,
    6. value: "+ 100%",
    7. valueprefix: "日",
    8. // valuesuffix={<Icon type="arrow-up" />
    9. valueIconType:'arrow-up'
    10. }
    11. ]

    下面带着问题看antd的代码
    以研究 Checkbox 为例子

    1. import { Checkbox } from 'antd';
    2. const CheckboxGroup = Checkbox.Group;
    3. ## 方便的从数组生成 Checkbox 组
    4. <Checkbox.Group
    5. options={options}
    6. defaultValue={['Apple']}
    7. onChange={onChange}
    8. />
    9. const options = [
    10. { label: 'Apple', value: 'Apple' },
    11. { label: 'Pear', value: 'Pear' },
    12. { label: 'Orange', value: 'Orange' },
    13. ];
    14. # 也支持单独
    15. <Checkbox.Group style={{ width: '100%' }} onChange={onChange}>
    16. <Checkbox value="A">A</Checkbox>
    17. <Checkbox value="C">C</Checkbox>
    18. </Checkbox.Group>

    5、通过读源码发现的一个设计
    组件接受传入class前缀,
    less里的class设置居然可以是变量!!
    (即js又向css传值了 咋做到的orz
    一般对于这种情况 我都是写完所有的class
    比如一个音乐 close 、open; 我分别写了close下的状态 和 open的状态
    但现在 它直接

    1. const { prefixCls: customizePrefixCls } = props;
    2. # index.less
    3. .@{checkbox-prefix-cls} {
    4. .@{checkbox-prefix-cls}-wrapper:hover,
    5. .@{checkbox-prefix-cls}-wrapper:hover &-inner,
    6. &:hover &-inner,
    7. &-input:focus + &-inner {}
    8. &-checked::after { # 还可以直接 &-input !!
    9. }
    10. }