当我想要设计出这样的组件时,我面临的困难:
<Statistic>
<StatisticItem
title="回答数"
help="您的历史所有回答"
data={983}
value="+ 100%"
// precision={2}
// valueStyle={{ color: '#3f8600' }}
valueprefix="日"
valuesuffix={<Icon type="arrow-up" />}
/>
<StatisticItem
title="回答数"
help="您的历史所有回答"
data={983}
value="+ 100%"
// precision={2}
// valueStyle={{ color: '#3f8600' }}
valueprefix="日"
valuesuffix={<Icon type="arrow-up" />}
/>
</Statistic>
1、StatisticItem作为Statistic的子组件,Statistic怎么读取到他的子组件的。
Statistic包裹StatisticItem的主要作用是 作为父容器,提供均等分布局
这里好像没啥作用?
Statistic只负责提供外层的css即可?
checkbox的设计:
根据组件接口响应即可 无需管group的事( 如果group控制item的生成 ,那就直接绑定在group上
<Checkbox defaultChecked={false} disabled />
return (
// eslint-disable-next-line jsx-a11y/label-has-associated-control
<label
className={classString}
style={style}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
>
<RcCheckbox
{...checkboxProps}
prefixCls={prefixCls}
className={checkboxClass}
ref={this.saveCheckbox}
/>
{children !== undefined && <span>{children}</span>}
</label>
);
对于 group:
判断是否有children,
如果有那么group就负责提供一下wrap的外壳
如果没有,且options不为空 那么就由group控制生成checkbox
const options = [
{ label: 'Apple', value: 'Apple' },
{ label: 'Pear', value: 'Pear' },
{ label: 'Orange', value: 'Orange' },
];
// GROUP 组件需要针对这种传入形式 帮用户生成 {}结果的数组item
// const options = ['Apple','Pear','Orange'] 数组item为string 默认value、label等都一致
<Checkbox.Group
options={options}
defaultValue={['Apple']}
onChange={onChange}
/>
===>
<Checkbox.Group style={{ width: '100%' }} onChange={onChange}>
<Checkbox value="Apple">Apple</Checkbox>
<Checkbox value="Pear">Pear</Checkbox>
</Checkbox.Group>
# 帮生成 {}结果的数组item
getOptions() {
const { options } = this.props;
// https://github.com/Microsoft/TypeScript/issues/7960
return (options as Array<CheckboxOptionType>).map(option => {
if (typeof option === 'string') {
return {
label: option,
value: option,
} as CheckboxOptionType;
}
return option;
});
}
children的处理:修改props.chilren 将新的render挂载在children上(有点意外,不过这样确实有道理
option结构
const options = [
{ label: 'Apple', value: 'Apple' },
{ label: 'Pear', value: 'Pear' },
{ label: 'Orange', value: 'Orange' },
];
===========
let { children } = props;
if (options && options.length > 0) {
children = this.getOptions().map(option => (
<Checkbox
prefixCls={prefixCls}
key={option.value.toString()}
disabled={'disabled' in option ? option.disabled : props.disabled}
value={option.value}
checked={state.value.indexOf(option.value) !== -1}
onChange={option.onChange}
className={`${groupPrefixCls}-item`}
>
{option.label}
</Checkbox>
));
}
const classString = classNames(groupPrefixCls, className);
return (
<div className={classString} style={style} {...domProps}>
{children}
</div
);
其中针对domProps的处理 使用了一些技巧
const obj = {name:2333}
const {name:newname} = obj; # 读取name属性 并使用新变量let newname = 2333;
此时name并未被生成变量;
const { prefixCls: customizePrefixCls, className, style, options, ...restProps } = props;
const domProps = omit(restProps, ['children', 'defaultValue', 'value', 'onChange', 'disabled']);
<div className={classString} style={style} {...domProps}>
omit这里对 domProps进行了对象属性简化,只传递有用的属性给下一级,有用的属性是[]里包含的那些
omit({ name: ‘Benjy’, age: 18 }, [ ‘name’ ]); // => { age: 18 }
2、StatisticItem
子组件 可以命名成 StatisticItem 也可以 Statistic.item
怎么实现的,思量的,命令方式也是一种讲究吗
===>
import Checkbox from './Checkbox';
import Group from './Group';
Checkbox.Group = Group;
export default Checkbox;
===> const {}
3、如果要支持 valueStyle 接口,组件使用者可以自己定义样式,组件内部应该怎么写呢?
===>
1、classname的处理 [组件使用者传来的classname、根据接口变化的classname
const { props } = this;
const {className} = props;
const classString = classNames(className, {
[`${prefixCls}-wrapper`]: true,
[`${prefixCls}-wrapper-checked`]: checkboxProps.checked,
[`${prefixCls}-wrapper-disabled`]: checkboxProps.disabled,
});
2、style<br />直接承接组件定义的style
<Checkbox.Group style={{ width: '100%' }} onChange={onChange}>
# 内部
const {style} = this.props;
return (
<div className={classString} style={style}>
{children}
</div>
)
4、是否可以提供一个更大的api挂载在Statistic上
直接传入数组 然后渲染生成即可 item即可
[
{
title: "回答数",
help: "您的历史所有回答",
data: 983,
value: "+ 100%",
valueprefix: "日",
// valuesuffix={<Icon type="arrow-up" />
valueIconType:'arrow-up'
}
]
下面带着问题看antd的代码
以研究 Checkbox 为例子
import { Checkbox } from 'antd';
const CheckboxGroup = Checkbox.Group;
## 方便的从数组生成 Checkbox 组
<Checkbox.Group
options={options}
defaultValue={['Apple']}
onChange={onChange}
/>
const options = [
{ label: 'Apple', value: 'Apple' },
{ label: 'Pear', value: 'Pear' },
{ label: 'Orange', value: 'Orange' },
];
# 也支持单独
<Checkbox.Group style={{ width: '100%' }} onChange={onChange}>
<Checkbox value="A">A</Checkbox>
<Checkbox value="C">C</Checkbox>
</Checkbox.Group>
5、通过读源码发现的一个设计
组件接受传入class前缀,
less里的class设置居然可以是变量!!
(即js又向css传值了 咋做到的orz
一般对于这种情况 我都是写完所有的class
比如一个音乐 close 、open; 我分别写了close下的状态 和 open的状态
但现在 它直接
const { prefixCls: customizePrefixCls } = props;
# index.less
.@{checkbox-prefix-cls} {
.@{checkbox-prefix-cls}-wrapper:hover,
.@{checkbox-prefix-cls}-wrapper:hover &-inner,
&:hover &-inner,
&-input:focus + &-inner {}
&-checked::after { # 还可以直接 &-input !!
}
}