Skeleton骨架屏

在需要等待加载内容的位置提供一个占位图形组合。

何时使用#

  • 网络较慢,需要长时间等待加载处理的情况下。

  • 图文信息内容较多的列表/卡片中。

  • 只在第一次加载数据的时候使用。

  • 可以被 Spin 完全代替,但是在可用的场景下可以比 Spin 提供更好的视觉效果和用户体验。

代码演示

最简单的占位效果。

expand codeexpand code
import { Skeleton } from 'antd';

ReactDOM.render(<Skeleton />, mountNode);

更复杂的组合。

expand codeexpand code
import { Skeleton } from 'antd';

ReactDOM.render(<Skeleton avatar paragraph={{ rows: 4 }} />, mountNode);

显示动画效果。

expand codeexpand code
import { Skeleton } from 'antd';

ReactDOM.render(<Skeleton active />, mountNode);


骨架按钮、头像、输入框和图像。

expand codeexpand code
import { Skeleton, Space, Divider, Switch, Form, Radio } from 'antd';

class Demo extends React.Component {
  state = {
    active: false,
    size: 'default',
    buttonShape: 'default',
    avatarShape: 'circle',
  };

  handleActiveChange = checked => {
    this.setState({ active: checked });
  };

  handleSizeChange = e => {
    this.setState({ size: e.target.value });
  };

  handleShapeChange = prop => e => {
    this.setState({ [prop]: e.target.value });
  };

  render() {
    const { active, size, buttonShape, avatarShape } = this.state;
    return (
      <>
        <Space>
          <Skeleton.Button active={active} size={size} shape={buttonShape} />
          <Skeleton.Button active={active} size={size} shape={buttonShape} />
          <Skeleton.Avatar active={active} size={size} shape={avatarShape} />
          <Skeleton.Input style={{ width: 200 }} active={active} size={size} />
        </Space>
        <br />
        <br />
        <Skeleton.Image />
        <Divider />
        <Form layout="inline" style={{ margin: '16px 0' }}>
          <Form.Item label="Active">
            <Switch checked={active} onChange={this.handleActiveChange} />
          </Form.Item>
          <Form.Item label="Size">
            <Radio.Group value={size} onChange={this.handleSizeChange}>
              <Radio.Button value="default">Default</Radio.Button>
              <Radio.Button value="large">Large</Radio.Button>
              <Radio.Button value="small">Small</Radio.Button>
            </Radio.Group>
          </Form.Item>
          <Form.Item label="Button Shape">
            <Radio.Group value={buttonShape} onChange={this.handleShapeChange('buttonShape')}>
              <Radio.Button value="default">Default</Radio.Button>
              <Radio.Button value="round">Round</Radio.Button>
              <Radio.Button value="circle">Circle</Radio.Button>
            </Radio.Group>
          </Form.Item>
          <Form.Item label="Avatar Shape">
            <Radio.Group value={avatarShape} onChange={this.handleShapeChange('avatarShape')}>
              <Radio.Button value="square">Square</Radio.Button>
              <Radio.Button value="circle">Circle</Radio.Button>
            </Radio.Group>
          </Form.Item>
        </Form>
      </>
    );
  }
}

ReactDOM.render(<Demo />, mountNode);

Ant Design, a design language

We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.

加载占位图包含子组件。

expand codeexpand code
import { Skeleton, Button } from 'antd';

class Demo extends React.Component {
  state = {
    loading: false,
  };

  showSkeleton = () => {
    this.setState({ loading: true });
    setTimeout(() => {
      this.setState({ loading: false });
    }, 3000);
  };

  render() {
    return (
      <div className="article">
        <Skeleton loading={this.state.loading}>
          <div>
            <h4>Ant Design, a design language</h4>
            <p>
              We supply a series of design principles, practical patterns and high quality design
              resources (Sketch and Axure), to help people create their product prototypes
              beautifully and efficiently.
            </p>
          </div>
        </Skeleton>
        <Button onClick={this.showSkeleton} disabled={this.state.loading}>
          Show Skeleton
        </Button>
      </div>
    );
  }
}

ReactDOM.render(<Demo />, mountNode);

在列表组件中使用加载占位符。

expand codeexpand code
import { Skeleton, Switch, List, Avatar } from 'antd';
import { StarOutlined, LikeOutlined, MessageOutlined } from '@ant-design/icons';

const listData = [];
for (let i = 0; i < 3; i++) {
  listData.push({
    href: 'https://ant.design',
    title: `ant design part ${i}`,
    avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
    description:
      'Ant Design, a design language for background applications, is refined by Ant UED Team.',
    content:
      'We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.',
  });
}

const IconText = ({ icon, text }) => (
  <span>
    {React.createElement(icon, { style: { marginRight: 8 } })}
    {text}
  </span>
);

class App extends React.Component {
  state = {
    loading: true,
  };

  onChange = checked => {
    this.setState({ loading: !checked });
  };

  render() {
    const { loading } = this.state;

    return (
      <>
        <Switch checked={!loading} onChange={this.onChange} />

        <List
          itemLayout="vertical"
          size="large"
          dataSource={listData}
          renderItem={item => (
            <List.Item
              key={item.title}
              actions={
                !loading && [
                  <IconText icon={StarOutlined} text="156" key="list-vertical-star-o" />,
                  <IconText icon={LikeOutlined} text="156" key="list-vertical-like-o" />,
                  <IconText icon={MessageOutlined} text="2" key="list-vertical-message" />,
                ]
              }
              extra={
                !loading && (
                  <img
                    width={272}
                    alt="logo"
                    src="https://gw.alipayobjects.com/zos/rmsportal/mqaQswcyDLcXyDKnZfES.png"
                  />
                )
              }
            >
              <Skeleton loading={loading} active avatar>
                <List.Item.Meta
                  avatar={<Avatar src={item.avatar} />}
                  title={<a href={item.href}>{item.title}</a>}
                  description={item.description}
                />
                {item.content}
              </Skeleton>
            </List.Item>
          )}
        />
      </>
    );
  }
}

ReactDOM.render(<App />, mountNode);

API#

Skeleton#

属性说明类型默认值
active是否展示动画效果booleanfalse
avatar是否显示头像占位图boolean | SkeletonAvatarPropsfalse
loading为 true 时,显示占位图。反之则直接展示子组件boolean-
paragraph是否显示段落占位图boolean | SkeletonParagraphPropstrue
title是否显示标题占位图boolean | SkeletonTitlePropstrue
round为 true 时,段落和标题显示圆角booleanfalse

SkeletonAvatarProps#

属性说明类型默认值
active是否展示动画效果,仅在单独使用头像骨架时生效booleanfalse
size设置头像占位图的大小number | large | small | default-
shape指定头像的形状circle | square-

SkeletonTitleProps#

属性说明类型默认值
width设置标题占位图的宽度number | string-

SkeletonParagraphProps#

属性说明类型默认值
rows设置段落占位图的行数number-
width设置段落占位图的宽度,若为数组时则为对应的每行宽度,反之则是最后一行的宽度number | string | Array<number | string>-

SkeletonButtonProps#

属性说明类型默认值
active是否展示动画效果booleanfalse
size设置按钮的大小large | small | default-
shape指定按钮的形状circle | round | default-

SkeletonInputProps#

属性说明类型默认值
active是否展示动画效果booleanfalse
size设置输入框的大小large | small | default-
Spin加载中Anchor锚点