Banner 公告条

横贯页面顶部的一条公告。

<script setup lang="ts">
  import { Banner, Link } from '@hina-ui/vue'
</script>

<template>
  <Banner closable>
    Hina UI 1.2 已发布。
    <Link href="#" underline>查看更新说明</Link>
  </Banner>
</template>
vue

用法

import { Banner } from '@hina-ui/vue'
ts

公告条贯穿页面整个宽度,通常放在页面最顶部,用于版本发布、停机维护、活动通知这类面向全站的信息。它是实底色块,没有圆角与边框。针对某次操作的消息使用 Alert,写在内容里的固定提示使用 Callout。需要随页面滚动固定在顶部时,加上 sticky top-0。

<script setup lang="ts">
  import { Banner } from '@hina-ui/vue'
</script>

<template>
  <Banner>本站将于 3 月 1 日 02:00 至 04:00 停机维护。</Banner>
</template>
vue

示例

色调

共六种色调,默认为 accent。图标随色调变化,icon 设为 false 时不显示图标。

<script setup lang="ts">
  import { Banner, Stack } from '@hina-ui/vue'
</script>

<template>
  <Stack class="w-full">
    <Banner tone="neutral">本站已启用新的评论系统。</Banner>
    <Banner tone="accent">Hina UI 1.2 已发布。</Banner>
    <Banner tone="info">当前浏览的是历史版本的文档。</Banner>
    <Banner tone="success">你的邮箱已完成验证。</Banner>
    <Banner tone="warning">本站将于今晚 02:00 停机维护。</Banner>
    <Banner tone="danger">支付服务暂时不可用,我们正在处理。</Banner>
    <Banner tone="accent" :icon="false">Hina UI 1.2 已发布。</Banner>
  </Stack>
</template>
vue

自定义图标

icon 插槽替换默认的图标。

<script setup lang="ts">
  import { Sparkles } from '@lucide/vue'
  import { Banner } from '@hina-ui/vue'
</script>

<template>
  <Banner>
    <template #icon><Sparkles class="size-4 shrink-0" /></template>
    周年活动进行中,全站图书限时八折。
  </Banner>
</template>
vue

操作

actions 插槽位于正文之后,用于放置一个按钮。

<script setup lang="ts">
  import { Banner, Button } from '@hina-ui/vue'
</script>

<template>
  <Banner tone="warning">
    登录状态将在 5 分钟后过期。
    <template #actions>
      <Button size="sm" tone="neutral">延长登录</Button>
    </template>
  </Banner>
</template>
vue

可关闭

设置 closable 后末端显示关闭按钮,关闭时触发 close 事件。v-model:open 控制显示与隐藏,是否记住用户关闭过由应用自行保存。

<script setup lang="ts">
  import { ref } from 'vue'
  import { Banner, Button, Stack } from '@hina-ui/vue'

  const open = ref(true)
</script>

<template>
  <Stack class="min-h-24 w-full">
    <Banner v-model:open="open" tone="success" closable>你的邮箱已完成验证。</Banner>
    <Button variant="soft" tone="neutral" :disabled="open" class="self-start" @click="open = true">
      再次显示
    </Button>
  </Stack>
</template>
vue

多条公告

items 传入多条公告,item 插槽决定每条的内容。多于一条时末端出现上一条、下一条按钮与计数,到末尾后回到开头,v-model:index 绑定当前是第几条。每条可以带自己的 tone 与 icon,没有的沿用公告条的。切换时图标与正文作为一个整体按方向滑动,底色与字色平滑过渡。关闭按钮关闭的是整条公告栏。

<script setup lang="ts">
  import { Sparkles } from '@lucide/vue'
  import { Banner, Link, type BannerNotice } from '@hina-ui/vue'

  const notices: (BannerNotice & { text: string; link?: string })[] = [
    { text: 'Hina UI 1.2 已发布。', link: '查看更新说明' },
    { text: '本站将于 3 月 1 日 02:00 至 04:00 停机维护。', tone: 'warning' },
    { text: '周年活动进行中,全站图书限时八折。', link: '了解详情', icon: Sparkles },
  ]
</script>

<template>
  <Banner :items="notices" closable>
    <template #item="{ item }">
      {{ item.text }}
      <Link v-if="item.link" href="#" underline>{{ item.link }}</Link>
    </template>
  </Banner>
</template>
vue

自动轮播

autoplay 传入毫秒数后按此间隔自动切到下一条。指针悬停、焦点在公告条内或页面不可见时暂停,离开后继续;用户在系统中选择了减少动态效果时不自动切换。

<script setup lang="ts">
  import { Banner } from '@hina-ui/vue'

  const notices = [
    { text: '新增书评 86 条,活跃读者 1,204 人。' },
    { text: '本周最受欢迎的作品是《狼と香辛料》。' },
    { text: '书架支持按标签筛选了。' },
  ]
</script>

<template>
  <Banner :items="notices" :autoplay="4000" tone="info">
    <template #item="{ item }">{{ item.text }}</template>
  </Banner>
</template>
vue

在 AppShell 里

AppShell 的 banner 插槽位于最顶部,横贯侧栏与主区域。公告条关闭后,下方的侧栏与主区域一起上移补满。

首页

关闭公告条后,侧栏与主区域一起上移补满。

<script setup lang="ts">
  import {
    AppShell,
    Banner,
    Heading,
    Link,
    NavLink,
    Sidebar,
    SidebarTrigger,
    Text,
  } from '@hina-ui/vue'
</script>

<template>
  <AppShell collapsible="hidden" class="border-line h-96 w-full rounded-lg border">
    <template #banner>
      <Banner closable>
        Hina UI 1.2 已发布。
        <Link href="#" underline>查看更新说明</Link>
      </Banner>
    </template>

    <template #sidebar>
      <Sidebar>
        <NavLink href="#" active label="首页">首页</NavLink>
        <NavLink href="#" label="我的书架">我的书架</NavLink>
      </Sidebar>
    </template>

    <template #header>
      <SidebarTrigger />
      <Heading :level="2" size="sm">首页</Heading>
    </template>

    <Text size="sm" tone="muted" class="block p-6">关闭公告条后,侧栏与主区域一起上移补满。</Text>
  </AppShell>
</template>
vue

行为

  • 视口宽度达到 640 像素时正文相对整条居中;更窄时正文靠起始边、占满关闭按钮之外的整行,按普通段落换行。
  • 关闭时收合并淡出,下方内容平滑上移。
  • 首次渲染时不播放出现动画。
  • 多条公告之间切换时,图标与正文一起按方向滑动:下一条从末端进入,上一条从起端进入,从右到左的书写方向下镜像。旧内容滑出后新内容滑入,公告条高度不变。
  • 切到色调不同的一条时,底色与字色平滑过渡。

无障碍

  • 公告条不是实时区域,屏幕阅读器按文档顺序朗读它。
  • 图标只是装饰,对辅助技术隐藏。
  • 多条公告手动切换时,内容所在的区域是礼貌级实时区域,屏幕阅读器会朗读新内容;自动轮播时不朗读,避免反复打断。
  • 关闭按钮的名称来自语言包的 close 条目,上一条、下一条按钮的名称来自 banner.prev 与 banner.next。

API

Props

属性
类型
默认值
说明
tone
'neutral' | 'accent' | 'info' | 'success' | 'warning' | 'danger'
'accent'
色调
icon
boolean
true
是否显示图标
closable
boolean
false
是否显示关闭按钮
open
boolean
true
是否显示,支持 v-model:open
items
T[]
—
多条公告,由 item 插槽渲染;每条可带 tone 与 icon
index
number
0
当前公告的序号,支持 v-model:index
autoplay
number
—
自动切换的间隔,毫秒
class
string
—
追加至公告条的类名

Events

事件
参数
说明
update:open
open: boolean
显示状态变化
update:index
index: number
当前公告变化
close
—
点击了关闭按钮

Slots

插槽
参数
说明
default
—
正文
item
{ item: T, index: number }
多条公告时每一条的内容
icon
—
替换图标
actions
—
正文之后的操作区