SwGallery

SwGallery 是不滚动、换行铺成等高网格的封面卡容器,与 SwRail(横滚横排)互补。它只管布局与取数节奏——卡片一切视觉(封面 / 角标 / 评分 / 集数)由 #default 作用域插槽业务渲染(通常放 SwImage),影 / 漫 / 小说封面对组件无差别。

海报墙:minItemWidth 自适应列数 + 按钮加载更多(剩余计数)

加载中...

列数控制(二选一)

模式写法适用
定卡宽自适应(默认):min-item-width="180"海报墙:窗口缩放列数跟着变(CSS Grid auto-fill + minmax)
锁定列数:columns="3" 或 :columns="{ mobile: 1, tablet: 2, desktop: 3 }"设计稿明确列数、超宽屏不许变(断点对齐 framework:mobile <768 / desktop ≥1024,缺档就近回退)

两者纯 CSS 实现(media query + CSS 变量),零 JS、SSR 安全。columns 传了即覆盖 minItemWidth。

columns 断点锁定(1/2/3 列)+ 自定义 #load-more 按钮

加载中...

loadMode auto:触底自动加载

加载中...

total 剩余计数 + 自动收敛

加载中...

加载更多(loadMode 三态,默认 button)

loadMode行为场景
'button'(默认)底部按钮,传 total 时带计数「加载更多 (N)」:再传 pageSize 则 N = min(pageSize, 剩余),否则 N = 剩余全列表页
'auto'近触底 IO 哨兵自动触发(autoThreshold 提前量;首屏未填满会持续填充)无限滚动列表
'none'纯网格分类首页多行内容块;页码翻页(配 SwPagination,替换式整组换 items)

追加式数据流:收到 @load-more 后往 items 追加;内部 busy 锁 + loading prop 双锁防重复触发(items 追加 / loading 收尾自动解锁,失败场景可重试)。无更多数据时置 finished(传了 total 时 remaining=0 自动视为到底)。

失败重试:请求失败时父层置 error: true,加载区变「加载失败,点击重试」按钮(点击照常 emit @load-more,父层重试发请求前清 error);auto 模式失败时哨兵移除、转手动重试(防失败自动循环),error 清掉并追加后自动恢复。

失败重试:error 置位 → 重试按钮 → 清错继续(含 page-size 按钮计数)

加载中...

loadMode none:分类首页内容块(纯网格)

加载中...

标准用法

<script setup lang="ts">
const items = ref<Movie[]>([])
const total = ref(0)
const loading = ref(false)

async function loadMore() {
  loading.value = true
  try {
    const r = await request<MovieList>('/movie/list', { body: { offset: items.value.length } })
    items.value = [...items.value, ...r.list]
    total.value = +r.total
  } finally {
    loading.value = false
  }
}
await loadMore()
</script>

<template>
  <SwGallery :items="items" :total="total" :loading="loading" :min-item-width="180" @load-more="loadMore">
    <template #default="{ item }">
      <SwLink :to="`/movie/${item.id}`" :track="{ /* 卡片埋点走 SwLink,网格不内置 */ }">
        <SwImage :src="item.img" :alt="item.name" ratio="2/3" />
        <p>{{ item.name }}</p>
      </SwLink>
    </template>
  </SwGallery>
</template>

Props

名称类型必填默认值说明
itemsT[]✓—追加式数据源(泛型,组件不关心形状)
minItemWidthnumber | string240卡片最小宽(auto-fill 模式)。number 视作 px;string 原样透传,可传 min(15.625rem, 46%) / var(--x)
columnsnumber | { mobile?, tablet?, desktop? }undefined锁定列数,传了覆盖 minItemWidth
loadMode'button' | 'auto' | 'none''button'加载更多模式
loadingbooleanfalse外部加载态(双锁之一)
finishedbooleanfalse无更多数据
totalnumberundefined总数 → 按钮计数;remaining=0 视为到底
pageSizenumberundefined每次加载条数 → 按钮计数显示 min(pageSize, 剩余);不传退回剩余数
errorbooleanfalse上次加载失败(父层维护);true 时加载区变「加载失败,点击重试」
autoThresholdnumber | string200auto 哨兵提前量。number 视作 px;string 原样透传给 rootMargin,可用 % 按视口比例预取。运行时可改(会重建 IO)
ariaLabelstringundefined传了才输出 role="region" + aria-label

Events

名称携带说明
load-more—请父层追加 items(双锁内防重复)

Slots

名称作用域说明
default{ item, index }每张卡片(业务渲染全部视觉)
load-more{ loading, remaining, error }自定义加载更多按钮区
finished—到底文案(默认「已经到底了」)
empty—items 为空的空态(默认「暂无内容」)

Expose

名称说明
loadMore()命令式触发一次加载(受双锁约束)

CSS 变量

变量默认说明
--sw-gallery-gap1rem网格间距
--sw-gallery-min由 minItemWidth 写入最小卡宽
--sw-gallery-template未设时走 minItemWidth 自适应自定义断点逃生舱:columns prop 只有 mobile/tablet/desktop 三档,需要更多断点时不传 columns、改在自己的媒体查询里设本变量(值即 grid-template-columns)。与 columns 二选一,传了 prop 会覆盖它

注意事项

  • 埋点不内置:卡片曝光 / 点击走卡片内 SwLink :track;网格本身零上报。
  • 翻页器场景:页码翻页是替换式数据流,用 loadMode="none" + SwPagination 组合(framework#131),不要把页码塞进 Gallery。
  • 选型对照(横滚 / 轮播 / 视频流 / 网格)见 SwRail 选型表。
  • 失败重试要同时传 :loading:error / loading 都由父层维护;失败时只传 :error 不传 :loading,内部加载锁不释放、重试点击无效——请同时传 :loading,并在重试发请求前把 error 清回 false。
  • @load-more 要配 :finished 或 :total:两者都不传则永远判不到「到底」,button 模式按钮常驻、auto 模式哨兵反复触发拉空页(死循环)。无更多数据时置 :finished="true",或传 :total 让剩余归零自动收敛。

相关