特性
安装
别忘了引入样式:
图标
lucide-vue-next 作为图标。如果你想换一套图标库,可以用 #controls 和 #navigation 作用域插槽提供自己的实现。基本用法
引入样式表和 LightboxOverlay 组件,然后用 v-model:is-open.
作用域插槽
六个具名作用域插槽让你完全定制浮层的各个界面。省略插槽即保留内置默认实现;插槽内部什么都不放(例如用 v-if="false")就能把该部分整个隐藏。
| 插槽 | 作用域 | 说明 |
|---|---|---|
| #slide | SlideSlotScope | 替换单张幻灯片的内容(视频幻灯片必须提供) |
| #controls | ControlsSlotScope | 替换顶部控件栏(关闭、计数、全屏) |
| #navigation | NavigationSlotScope | 替换上一张 / 下一张导航箭头 |
| #info | InfoSlotScope | 替换底部的标题 / 描述渐变浮层 |
| #loading | LoadingSlotScope | 自定义加载提示 |
| #error | ErrorSlotScope | 自定义错误提示 |
视频支持
视频幻灯片是按需开启的,默认产物里不会掺进音视频相关代码。调用 useVideoSlideRenderer(items) 并把返回的 VideoSlideRenderer / VideoControlsRenderer 接到浮层的 #slide 和 #controls 插槽上。再把浮层包进返回的 SoundProvider 里,内置的声音开关才有上下文。
<video> 元素与 vue reel-player 用的是同一套模式 —— 在 iOS 上切换幻灯片时播放不会中断,也不需要每张都由用户手势触发。全屏
使用 useFullscreen from @reelkit/vue 来观察或切换某个引用元素的全屏状态。Lightbox内置的全屏按钮用的就是同一个组合式函数。
URL 状态
用 useOverlayUrlState from @reelkit/vue 构建控制器,再把它交给 LightboxUrlOverlay 作为 controller,地址栏就拥有了这个画廊:参数指向某张幻灯片时它自己打开,参数消失时关闭。链接可以分享,返回键会关闭画廊。它是一个独立于 LightboxOverlay的组件,因此每个组件都只有一个打开状态的驱动源 —— 要么是 is-open 模型,要么是 URL controller,绝不会同时用两个。
只有从应用内部打开时返回键才会关闭 —— 因为那次链接压入了一条记录,返回就会弹回画廊。在新标签页里直接打开的分享链接背后没有历史,浏览器返回会离开站点;这时关闭按钮或 Escape 会就地移除参数,把你留在画廊上。
这个组合式函数接受一个选项对象,返回一个 UrlStateController (带 set, index, value)。留着它就能编程式地控制: set 是浮层内部使用的底层写入(切换幻灯片,以及用 set(null) 关闭)。它同样可以编程式驱动浮层 —— set(index) 会打开它,效果和导航到该参数一样。不过打开时更推荐用链接:href 可以分享、能在新标签页打开、返回键会关闭它 —— 全都不用写处理函数。
完整的 useOverlayUrlState 选项(param, adapter, codec, locator):见 Vue API 参考.
LightboxUrlOverlay 本身只接受 :controller (必填)、一个 @close 事件,外加所有视觉和行为属性 LightboxOverlay 所转发的(items, transition-fn、各种作用域插槽等等)—— 但没有 is-open.
- 打开会花掉一条历史记录;翻页则是替换它,所以滑一百次也不会多出记录 —— 退一步永远就是离开画廊。
- 像
?photo=3会把画廊直接打开到那一张。指向不存在幻灯片的参数会从 URL 中移除,而不是继续声称一张打不开的幻灯片。
带路由的应用请传入适配器。 直接写历史会让路由器自己的 location 过期,下一次导航就会把参数丢掉。
稳定的链接。 索引是按位置的,所以列表重新排序后书签会打开另一张图片。 urlStableIdKey 按每个条目稳定的 id来寻址,扫描当前列表 —— 一次调用就覆盖了常见场景。
传入 hashCodec: base64UrlCodec 即可把 URL 中的 id 做 base64url 编码 —— 这是可逆的混淆,不是加密哈希。
想按别的字段(比如 slug)来寻址,或者用 locateAsync给无限信息流翻页,就自己构建 codec/locator : codec 把身份写进 URL, locator 负责找到它现在在哪。
无限 / 分页画廊。 locate 是同步的,因此只能回答已经加载过的条目 —— 只加载了 20 张时,指向第 400 张的分享链接就查不到。 locateAsync 是兜底,只有在未 命中时才调用:把需要的页拉进来,再返回该身份最终对应的索引。
快捷键
id来寻址?那就不必手写编解码器和定位器 —— 直接把 locateAsync 传给 urlStableIdKey({ items, locateAsync }) (未命中时它会去拉取,然后返回索引)。下面更完整的写法是给按别的字段寻址、或者需要完全掌控的场景准备的。在它未完成期间,Lightbox保持关闭,参数也不动,因此深链能熬过这次请求。 null 或请求被拒绝则会移除参数。如果结果在 URL 已经变化、Lightbox已关闭或组件已卸载之后才到达,就会被丢弃,因此慢请求不能打开一张没人要的幻灯片。它返回什么都以它为准 —— 它报告的是自己刚取到的数据的索引,Lightbox会直接采用,而不是再去读一遍 items,那里 Vue 还没有重新渲染。
API 参考
LightboxOverlay 属性
LightboxOverlayProps
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| isOpen | boolean | 必填 | 控制显示;为 false 时浮层会从 DOM 中移除。可用 v-model:is-open 双向绑定。 |
| items | LightboxItem[] | 必填 | 条目数组(图片或视频) |
| initialIndex | number | 0 | 初始可见条目的索引(从 0 开始) |
| transitionFn | TransitionTransformFn | slideTransition | 幻灯片过渡函数。可以引入内置的(slideTransition、flipTransition、lightboxFadeTransition、lightboxZoomTransition),也可以传自定义的。省略时默认为 slideTransition。 |
| showInfo | boolean | true | 是否渲染标题 / 描述信息浮层 |
| showControls | boolean | true | 是否渲染顶部控件栏(关闭、计数、全屏) |
| showNavigation | boolean | true | 是否渲染上一张 / 下一张导航箭头(仅桌面端) |
| transitionDuration | number | 300 | 幻灯片动画时长(毫秒) |
| swipeDistanceFactor | number | 0.12 | 触发切换所需的最小滑动距离占比(0–1) |
| swipeToCloseDirection | 'up' | 'down' | 'up' | 移动端滑动关闭手势的方向 |
| loop | boolean | false | 滑动器是否从最后一张绕回第一张 |
| enableNavKeys | boolean | true | 启用键盘方向键导航 |
| enableWheel | boolean | true | 启用鼠标滚轮导航 |
| wheelDebounceMs | number | 200 | 滚轮事件的防抖时长(毫秒) |
| ariaLabel | string | 'Image gallery' | 对话框区域的无障碍标签 |
LightboxUrlOverlay 属性
LightboxUrlOverlayProps
接受上面所有视觉和行为属性,除了 is-open,并把它换成 controller。它会发出 close, slide-change 和 api-ready,但没有 update:is-open. initial-index 在这里会被忽略 —— 由控制器的 position 决定打开哪一张,所以同时传入的值每次打开都会被覆盖。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| controller | UrlStateController | 必填 | 来自 useOverlayUrlState 的控制器。它的 position 决定浮层是否打开、显示哪一张;浮层会在切换幻灯片和关闭时通过它写回。 |
LightboxOverlay 事件
| 事件 | 负载 | 说明 |
|---|---|---|
| close | void | 用户关闭Lightbox时发出 |
| slide-change | number | 切换后发出,带上新的活动幻灯片索引 |
| api-ready | LightboxApi | 滑动器就绪时发出一次,同时暴露命令式 API |
| update:is-open | boolean | 关闭时发出;用于支持 v-model:is-open |
LightboxItem 接口
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| src | string | yes | 图片或视频的 URL |
| type | 'image' | 'video' | no | Item type. Defaults to 'image' |
| poster | string | no | 视频条目的缩略图 |
| title | string | no | 信息浮层中显示的标题 |
| description | string | no | 标题下方显示的描述 |
| width | number | no | 图片固有宽度(像素) |
| height | number | no | 图片固有高度(像素) |
插槽作用域类型
| 类型 | 字段 |
|---|---|
| SlideSlotScope | { item, index, size: [number, number], isActive, onReady, onWaiting, onError } |
| ControlsSlotScope | { item, activeIndex, count, isFullscreen, onClose, onToggleFullscreen } |
| NavigationSlotScope | { item, activeIndex, count, onPrev, onNext } |
| InfoSlotScope | { item, index } |
| LoadingSlotScope | { item, activeIndex } |
| ErrorSlotScope | { item, activeIndex } |
过渡动画
把任意 TransitionTransformFn 通过 transition-fn 属性传入。只引入你用到的那个过渡,打包器就能把其余的摇掉。省略时默认为 slideTransition 。
| 函数 | 说明 |
|---|---|
| slideTransition | 默认。幻灯片之间横向平移;从 @reelkit/vue 重新导出。 |
| lightboxFadeTransition | 交叉淡入淡出,带轻微的横向位移。仅存在于 @reelkit/vue-lightbox。 |
| flipTransition | 绕 Y 轴的 3D 翻转;从 @reelkit/vue 重新导出。 |
| lightboxZoomTransition | 进入的幻灯片从 70% 放大到 100% 并淡入。仅存在于 @reelkit/vue-lightbox。 |
内容加载与错误处理
当你通过 #slide 插槽接管渲染时,插槽作用域上有三个生命周期回调可用于上报加载状态。Lightbox会逐张跟踪状态,并据此显示转圈动画或错误图标。内容预加载器会缓存损坏的 URL,因此再次访问失败的幻灯片不会重试。
生命周期回调
| 回调 | 类型 | 说明 |
|---|---|---|
| onReady | () => void | 通知幻灯片内容已成功加载(例如图片解码完成) |
| onWaiting | () => void | 通知幻灯片内容正在加载 / 缓冲(显示转圈动画) |
| onError | () => void | 通知幻灯片内容加载失败(显示错误图标) |