ProComponents, templates & AI tooling
HeroUI
27.7k

Skeleton

Skeleton 从 HeroUI v2 到 v3 的迁移指南。

完整的 API 参考、样式指南与高级示例请参阅 v3 Skeleton 文档。本指南只关注从 HeroUI v2 的迁移。

结构变化

在 v2 中,Skeleton 会包裹其子节点,并根据 isLoaded 显示或隐藏:

import { Skeleton } from "@heroui/react";

export default function App() {
  const isLoaded = false;
  
  return (
    <Skeleton isLoaded={isLoaded}>
      <div className="h-24 bg-secondary" />
    </Skeleton>
  );
}

在 v3 中,Skeleton 改为独立的占位符,由你自己手动控制其可见性:

import { Skeleton } from "@heroui/react";

export default function App() {
  const isLoaded = false;
  
  return (
    <>
      {!isLoaded ? (
        <Skeleton className="h-24 rounded-lg" />
      ) : (
        <div className="h-24 bg-secondary" />
      )}
    </>
  );
}

主要变化

1. 组件行为

v2: 包裹子节点,并根据 isLoaded 显示/隐藏
v3: 独立占位符——可见性由你自行控制

2. Prop 变更

v2 propv3 位置说明
isLoaded通过条件渲染手动控制可见性
disableAnimationanimationType改用 animationType="shimmer" | "pulse" | "none"(用 "none" 禁用动画)
classNames直接使用 className prop
childrenSkeleton 不再包裹内容

3. 新增 prop

  • animationType —— 控制动画类型:"shimmer"(默认)、"pulse""none"

迁移示例

配合加载状态

import { useState } from "react";

const [isLoaded, setIsLoaded] = useState(false);

<Skeleton className="rounded-lg" isLoaded={isLoaded}>
  <div className="h-24 rounded-lg bg-secondary" />
</Skeleton>
import { useState } from "react";

const [isLoaded, setIsLoaded] = useState(false);

{!isLoaded ? (
  <Skeleton className="h-24 rounded-lg" />
) : (
  <div className="h-24 rounded-lg bg-secondary" />
)}

独立 Skeleton

<div className="flex items-center gap-3">
  <Skeleton className="flex rounded-full w-12 h-12" />
  <div className="w-full flex flex-col gap-2">
    <Skeleton className="h-3 w-3/5 rounded-lg" />
    <Skeleton className="h-3 w-4/5 rounded-lg" />
  </div>
</div>
<div className="flex items-center gap-3">
  <Skeleton className="h-12 w-12 shrink-0 rounded-lg" />
  <div className="flex-1 space-y-2">
    <Skeleton className="h-3 w-full rounded" />
    <Skeleton className="h-3 w-4/5 rounded" />
  </div>
</div>

动画类型

{/* Shimmer (default) */}
<Skeleton>
  <div className="h-24 bg-default-300" />
</Skeleton>

{/* No animation */}
<Skeleton disableAnimation>
  <div className="h-24 bg-default-300" />
</Skeleton>
{/* Shimmer (default) */}
<Skeleton animationType="shimmer" className="h-24 rounded-lg" />

{/* Pulse */}
<Skeleton animationType="pulse" className="h-24 rounded-lg" />

{/* No animation */}
<Skeleton animationType="none" className="h-24 rounded-lg" />

复杂示例:带内容的 Card

import { useState } from "react";

const [isLoaded, setIsLoaded] = useState(false);

<Card className="w-[200px] space-y-5 p-4" radius="lg">
  <Skeleton className="rounded-lg" isLoaded={isLoaded}>
    <div className="h-24 rounded-lg bg-secondary" />
  </Skeleton>
  <div className="space-y-3">
    <Skeleton className="w-3/5 rounded-lg" isLoaded={isLoaded}>
      <div className="h-3 w-full rounded-lg bg-secondary" />
    </Skeleton>
    <Skeleton className="w-4/5 rounded-lg" isLoaded={isLoaded}>
      <div className="h-3 w-full rounded-lg bg-secondary-300" />
    </Skeleton>
  </div>
</Card>
import { useState } from "react";

const [isLoaded, setIsLoaded] = useState(false);

<Card className="w-[250px] space-y-5 rounded-lg p-4">
  {!isLoaded ? (
    <>
      <Skeleton className="h-32 rounded-lg" />
      <div className="space-y-3">
        <Skeleton className="h-3 w-3/5 rounded-lg" />
        <Skeleton className="h-3 w-4/5 rounded-lg" />
      </div>
    </>
  ) : (
    <>
      <div className="h-32 rounded-lg bg-secondary" />
      <div className="space-y-3">
        <div className="h-3 w-3/5 rounded-lg bg-secondary" />
        <div className="h-3 w-4/5 rounded-lg bg-secondary-300" />
      </div>
    </>
  )}
</Card>

同步的微光效果

在 v3 中,你可以创建一次性扫过所有 Skeleton 的同步微光效果。在父容器上加上 skeleton--shimmer 类,并将每个子 Skeleton 的 animationType 设为 "none"

{/* The parent container drives a single shimmer across all children */}
<div className="skeleton--shimmer space-y-4 rounded-lg p-4">
  <Skeleton animationType="none" className="h-32 rounded-lg" />
  <div className="space-y-3">
    <Skeleton animationType="none" className="h-3 w-3/5 rounded-lg" />
    <Skeleton animationType="none" className="h-3 w-4/5 rounded-lg" />
  </div>
</div>

这种方式适用于卡片类布局——你需要的是一次统一扫过整体的微光,而不是每个 Skeleton 各自独立地播放动画。

全局动画配置

在 v3 中,你可以通过 CSS 变量在全局设置默认的动画类型:

:root {
  --skeleton-animation: pulse; /* shimmer, pulse, or none */
}

各个组件上的 animationType prop 可以覆盖该默认值。

总结

  1. 不再包裹子节点:Skeleton 不再包裹其子节点——它本身就是一个独立的占位符
  2. 不再有 isLoaded prop:通过条件渲染手动控制可见性
  3. 动画控制disableAnimationanimationType"shimmer""pulse""none"
  4. 样式classNames → 直接使用 className prop
  5. 简化的 API:组件更简单,专注于占位符职责
  6. 同步微光:在父容器上使用 skeleton--shimmer 类,并将子 Skeleton 的 animationType 设为 "none",即可实现统一的微光扫过效果

本页目录