组件的结构: 组件 = 容器 -> Spin -> 内容 ?? 空数据占位
容器:提供 className 设置、提供内联 style 设置,负责控制 border 样式和内容的公共样式。
Spin:展示 loading 时的动画
内容:负责渲染数据,样式尽量从容器继承。
组件接口
组件容器的 className 设置公共前缀即 prefixCls。(less 通过变量设置公共前缀)
输入型组件提供 value 和 onChange,便于对接 form。
示例:
getPrefixCls:
import classnames from 'classnames'
import { ClassValue } from 'classnames/types'
const CommonPrefixCls = 'nextpl'
export const getPrefixCls = (suffixCls?: string, ...classes: ClassValue[]) => {
const currentCls = suffixCls
? `${CommonPrefixCls}-${suffixCls}`
: CommonPrefixCls
return classnames(currentCls, ...classes)
}
组件:
import { Spin } from 'antd'
import React, { CSSProperties } from 'react'
export interface ListViewProps {
loading?: boolean
data: any
className?: string
style?: CSSProperties
}
export const ListView = ({
loading,
data,
className,
style,
}: ListViewProps) => {
let content = <>暂无数据</>
if (data) {
content = <>{data}</>
}
return (
<div className={getPrefixCls('listView', className)} style={style}>
<Spin spinning={loading}>{content}</Spin>
</div>
)
}
vscode 代码片段:
输入 jsx-comp 回车触发
{
"Print to console": {
"prefix": "jsx-comp",
"body": [
"import './style.less'",
"",
"import { Spin } from 'antd'",
"import classnames from 'classnames'",
"import React, { CSSProperties } from 'react'",
"",
"export interface ${1:Component}Props {",
" loading?: boolean",
" data: any",
" className?: string",
" style?: CSSProperties",
"}",
"",
"export const ${1:Component} = ({",
" loading,",
" data,",
" className,",
" style,",
"}: ${1:Component}Props) => {",
" let content = <>暂无数据</>",
" if (data) {",
" content = <>内容</>",
" }",
" return (",
" <div className={classnames('${1:Component}', className)} style={style}>",
" <Spin spinning={loading}>{content}</Spin>",
" </div>",
" )",
"}"
],
"description": "jsx comp tpl."
}
}
组件设计2
import { Empty, Skeleton } from 'antd';
import React, { CSSProperties } from 'react';
export interface ListViewProps {
loading?: boolean;
data: any;
className?: string;
style?: CSSProperties;
}
export const ListView = ({ loading, data, className, style }: ListViewProps) => {
let children = <></>;
if (loading) {
children = <Skeleton active title paragraph />;
} else if (data) {
children = <span>{data}</span>;
} else {
children = <Empty description="无法加载" />;
}
return (
<div className={getPrefixCls('listView', className)} style={style}>
{children}
</div>
);
};