ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Vant ImagePreview 图片预览组件完全指南:组件调用与函数调用全解析

Vant ImagePreview 图片预览组件完全指南:组件调用与函数调用全解析 Vant ImagePreview 图片预览组件完全指南组件调用与函数调用全解析【免费下载链接】vantA lightweight, customizable Vue UI library for mobile web apps.项目地址: https://gitcode.com/GitHub_Trending/va/vant导读本文系统讲解 Vant 移动端组件库中 ImagePreview 图片预览组件的完整使用方案覆盖showImagePreview函数调用与van-image-preview组件调用两种方式并结合仓库源码深入剖析其手势缩放、异步关闭、插槽定制等底层实现原理。读完本文你将能快速在 Vue 3 项目中落地全屏图片预览、自定义页码/关闭按钮、嵌入视频内容并掌握通过 CSS 变量定制主题的能力。功能概览与组件引入ImagePreview 用于图片放大预览它构建在 Vant 的 Popup 弹出层与 Swipe 轮播组件之上支持左右滑动切换、双指捏合缩放、双击缩放、长按监听等完整移动端手势。组件同时支持组件调用与函数调用两种方式开发者可按场景灵活选择。在入口文件 packages/vant/src/index.ts 中ImagePreview 与showImagePreview均作为具名导出提供给开发者。通过以下方式全局注册组件import { createApp } from vue; import { ImagePreview } from vant; const app createApp(); app.use(ImagePreview);从源码 packages/vant/src/image-preview/index.ts 可以看到ImagePreview通过withInstall包装为可app.use的插件并同步导出了imagePreviewProps、showImagePreview以及ImagePreviewProps、ImagePreviewOptions、ImagePreviewInstance、ImagePreviewScaleEventParams等类型定义同时它向 Vue 的全局组件注册表声明了VanImagePreview因此在模板中可直接使用van-image-preview标签。更多注册方式按需引入、unplugin-vue-components 自动引入等可参考 组件注册。函数调用showImagePreview为便于快速唤起全局图片预览Vant 提供了showImagePreview辅助函数。调用后组件会被渲染到页面中默认挂载到body无需在模板中预先声明。基础用法直接传入图片 URL 数组即可展示import { showImagePreview } from vant; showImagePreview([ https://fastly.jsdelivr.net/npm/vant/assets/apple-1.jpeg, https://fastly.jsdelivr.net/npm/vant/assets/apple-2.jpeg, ]);传入配置对象showImagePreview支持传入ImagePreviewOptions配置对象并通过startPosition指定初始展示的图片索引import { showImagePreview } from vant; showImagePreview({ images: [ https://fastly.jsdelivr.net/npm/vant/assets/apple-1.jpeg, https://fastly.jsdelivr.net/npm/vant/assets/apple-2.jpeg, ], startPosition: 1, });返回值与手动关闭showImagePreview会返回一个 ImagePreview 实例通过实例上的close()方法可手动关闭预览。结合beforeClose即可实现异步关闭先拦截关闭动作延迟后再真正关闭。import { showImagePreview } from vant; const instance showImagePreview({ images: [ https://fastly.jsdelivr.net/npm/vant/assets/apple-1.jpeg, https://fastly.jsdelivr.net/npm/vant/assets/apple-2.jpeg, ], beforeClose: () false, }); setTimeout(() { // 调用实例上的 close 方法手动关闭图片预览 instance.close(); }, 2000);函数调用的底层实现从源码 packages/vant/src/image-preview/function-call.tsx 可以看清showImagePreview的实现机制函数签名支持string[] | ImagePreviewOptions两种入参形式当传入数组时内部会将其规范化为{ images: options, startPosition }对象第二参数可作为起始位置。组件实例通过mountComponent与usePopupState懒加载创建首次调用时initInstance()才会把VanImagePreview挂载到页面之后复用同一个全局实例。传入的配置会与defaultConfig默认配置合并extend({}, defaultConfig, options)因此未指定的选项全部采用默认值例如loop: true、maxZoom: 3、minZoom: 1/3、closeOnPopstate: true、closeIcon: clear、teleport: body等。预览关闭后onClosed会将images清空避免下次打开残留旧数据。组件调用ImagePreview 组件当需要在预览中嵌入组件或自定义内容时如播放视频、展示富交互内容应直接使用 ImagePreview 组件通过v-model:show控制显隐。基础用法与 index 插槽van-image-preview v-model:showshow :imagesimages changeonChange template v-slot:index第{{ index 1 }}页/template /van-image-previewimport { ref } from vue; export default { setup() { const show ref(false); const index ref(0); const images [ https://fastly.jsdelivr.net/npm/vant/assets/apple-1.jpeg, https://fastly.jsdelivr.net/npm/vant/assets/apple-2.jpeg, ]; const onChange (newIndex) { index.value newIndex; }; return { show, index, images, onChange, }; }, };index插槽用于自定义页码内容其参数{ index }为当前图片索引从 0 开始。若未提供该插槽组件默认渲染${index 1} / ${images.length}格式的页码。使用 image 插槽嵌入自定义内容通过image插槽可以完全替换默认的img渲染例如展示视频van-image-preview v-model:showshow :imagesimages :close-on-click-imagefalse template #image{ src } video stylewidth: 100%; controls source :srcsrc / /video /template /van-image-previewimport { ref } from vue; export default { setup() { const show ref(false); const images [ https://www.w3school.com.cn/i/movie.ogg, https://www.w3school.com.cn/i/movie.ogg, https://www.w3school.com.cn/i/movie.ogg, ]; return { show, images, }; }, };提示在上例中将close-on-click-image设置为false可避免点击视频时意外关闭预览。image插槽还透出style与onLoad两个参数style是组件内部根据缩放/平移状态计算出的图片样式transformonLoad是图片加载完成后的回调。绑定它们可让自定义img标签同样支持缩放平移van-image-preview v-model:showshow :imagesimages :close-on-click-imagefalse template #image{ src, style, onLoad } img :srcsrc :style[{ width: 100% }, style] loadonLoad / /template /van-image-preview从源码 packages/vant/src/image-preview/ImagePreviewItem.tsx 可以看到插槽渲染时组件会将src、imageStyle即style和内部onLoad处理器一并传入onLoad内部会读取naturalWidth/naturalHeight计算图片宽高比进而决定缩放边界与长图适配逻辑因此自定义图片内容时务必把它绑定到load事件上。该机制的测试用例可见 packages/vant/src/image-preview/test/index.spec.ts分别验证了自定义img、嵌入video、透传style三种场景。API 参考方法方法名说明参数返回值showImagePreview展示一个全屏的图片预览组件string[] | ImagePreviewOptionsImagePreview 实例ImagePreviewOptions调用showImagePreview方法时支持传入以下选项参数名说明类型默认值images需要预览的图片 URL 数组string[][]startPosition图片预览起始位置索引number | string0swipeDuration动画时长单位为msnumber | string300showIndex是否显示页码booleantrueshowIndicators是否显示轮播指示器booleanfalseloop是否开启循环播放booleantruedoubleScalev4.7.2是否启用双击缩放手势禁用后点击时会立即关闭图片预览booleantrueonClose关闭时的回调函数Function-onChange切换图片时的回调函数回调参数为当前索引Function-onScale缩放图片时的回调函数回调参数为当前索引和当前缩放值组成的对象Function-beforeClose关闭前的回调函数返回false可阻止关闭支持返回 Promise(active: number) boolean | Promiseboolean-closeOnPopstate是否在页面回退时自动关闭booleantruecloseOnClickImagev4.8.3是否在点击图片后关闭图片预览booleantruecloseOnClickOverlayv4.6.4是否在点击遮罩层后关闭图片预览booleantrueverticalv4.8.6是否开启纵向手势滑动booleanfalseclassName自定义类名应用在图片预览的弹出层string | Array | object-maxZoom手势缩放时最大缩放比例number | string3minZoom手势缩放时最小缩放比例number | string1/3closeable是否显示关闭图标booleanfalsecloseIcon关闭图标名称或图片链接stringclearcloseIconPosition关闭图标位置可选值为top-left、bottom-left、bottom-rightstringtop-righttransition动画类名等价于 Vuetransition组件的name属性stringvan-fadeoverlayClass自定义遮罩层类名string | Array | object-overlayStyle自定义遮罩层样式object-teleport指定挂载的节点等同于 Teleport 组件的to属性string | Element-上述默认值在源码 packages/vant/src/image-preview/function-call.tsx 的defaultConfig中均有对应声明可作为权威参考。Props通过组件调用 ImagePreview 时支持以下 Props与 Options 一一对应采用 kebab-case 写法参数说明类型默认值v-model:show是否展示图片预览booleanfalseimages需要预览的图片 URL 数组string[][]start-position图片预览起始位置索引number | string0swipe-duration动画时长单位为 msnumber | string300show-index是否显示页码booleantrueshow-indicators是否显示轮播指示器booleanfalseloop是否开启循环播放booleantruedouble-scalev4.7.2是否启用双击缩放手势禁用后点击时会立即关闭图片预览booleantruebefore-close关闭前的回调函数返回false可阻止关闭支持返回 Promise(active: number) boolean | Promiseboolean-close-on-popstate是否在页面回退时自动关闭booleantrueclose-on-click-imagev4.8.3是否在点击图片后关闭图片预览booleantrueclose-on-click-overlayv4.6.4是否在点击遮罩层后关闭图片预览booleantrueverticalv4.8.6是否开启纵向手势滑动booleanfalseclass-name自定义类名string | Array | object-max-zoom手势缩放时最大缩放比例number | string3min-zoom手势缩放时最小缩放比例number | string1/3closeable是否显示关闭图标booleanfalseclose-icon关闭图标名称或图片链接stringclearclose-icon-position关闭图标位置可选值为top-left、bottom-left、bottom-rightstringtop-righttransition动画类名等价于 Vuetransition组件的name属性stringvan-fadeoverlay-class自定义遮罩层类名string | Array | object-overlay-style自定义遮罩层样式object-teleport指定挂载的节点等同于 Teleport 组件的to属性string | Element-组件 Props 的完整声明位于 packages/vant/src/image-preview/ImagePreview.tsx其中images、swipeDuration、startPosition等数值型参数使用makeNumericProp声明即同时接受数字与字符串形式。Events事件名说明回调参数close关闭时触发{ index: number, url: string }closed关闭且动画结束后触发-change切换当前图片时触发index: numberscale缩放当前图片时触发{ index: number, scale: number }long-press长按当前图片时触发{ index: number }实例方法通过 ref 获取 ImagePreview 实例后可调用以下方法详见组件实例方法方法名说明参数返回值prev切换到上一张图片--next切换到下一张图片--resetScale4.7.4重置当前图片的缩放比--swipeTo切换到指定位置index: number, options?: SwipeToOptions-实例方法通过useExpose暴露见 ImagePreview.tsx内部委托给底层 Swipe 组件的prev/next/swipeToresetScale则作用于当前激活的 ImagePreviewItem。测试用例 index.spec.ts 验证了swipeTo(2)后页码正确切换同文件第 444 行起 验证了缩放后调用resetScale可清空 transform。类型定义组件导出以下类型定义import type { ImagePreviewProps, ImagePreviewOptions, ImagePreviewInstance, ImagePreviewScaleEventParams, } from vant;ImagePreviewInstance是组件实例的类型配合 ref 使用可获得完整的类型提示import { ref } from vue; import type { ImagePreviewInstance } from vant; const imagePreviewRef refImagePreviewInstance(); imagePreviewRef.value?.swipeTo(1);类型定义详见 packages/vant/src/image-preview/types.tsImagePreviewExpose声明了resetScale、swipeTo、prev、next四个暴露方法ImagePreviewScaleEventParams描述scale事件参数结构。Slots名称说明参数index自定义页码内容{ index: 当前图片的索引 }cover自定义覆盖在图片预览上方的内容-image自定义图片内容{ src: 当前资源地址, onLoad: 加载图片函数, style: 当前图片样式 }onClose 回调参数参数名说明类型url当前图片 URLstringindex当前图片的索引值numberonScale 回调参数参数名说明类型index当前图片的索引值numberscale当前图片的缩放值number源码级原理剖析手势系统单击、双击、捏合与长按单张图片的交互实现在 ImagePreviewItem.tsx 中核心逻辑如下双指捏合缩放onTouchStart记录两指间距startDistanceonTouchMove中按startScale * distance / startDistance实时计算缩放值并以两指中心为锚点通过setScale同步修正位移moveX/moveY实现以手指为中心放大的体验。双击缩放checkTap中实现双击判定——两次点按间隔小于 250ms对齐 iOS 双击超时默认值即触发toggleScale在1与2倍之间切换若单击则延迟 250ms 后走关闭逻辑。当doubleScale为false时单击直接关闭预览对应文档禁用后点击立即关闭的说明。长按监听点按持续超过LONG_PRESS_START_TIME常量时触发longPress事件测试见 index.spec.ts。缩放边界setScale通过clamp将缩放值限制在[minZoom, maxZoom 1]区间松手onTouchEnd时若超过maxZoom会回弹到maxZoom小于 1 则resetScale复位。长图适配当图片宽高比大于根容器且达到longImageRatio 2.6阈值时判定为长图默认纵向展示并支持纵向平移isLongImage逻辑这也是vertical属性生效的场景之一。关闭拦截链路beforeClose无论是点击图片、遮罩层、关闭图标还是调用close()最终都会汇聚到emitClose它使用callInterceptor执行beforeClose拦截器见 ImagePreview.tsx回调返回false或 Promise resolve 为false即阻止关闭只有返回true才真正把show置为false。测试 index.spec.ts 验证了设置beforeClose: () true后点击不会关闭、只有显式置show: false才触发close事件。点击区域判定图片与遮罩checkClose通过事件目标判断点击发生在图片上还是遮罩SwipeItem 空白区域上再分别依据closeOnClickImage与closeOnClickOverlay决定是否关闭。测试用例分别验证了四种组合index.spec.ts。主题定制CSS 变量ImagePreview 提供下列 CSS 变量用于自定义样式可通过 ConfigProvider 组件 或直接覆盖实现定制变量声明见 index.less名称默认值描述--van-image-preview-index-text-colorvar(--van-white)页码文字颜色--van-image-preview-index-font-sizevar(--van-font-size-md)页码字号--van-image-preview-index-line-heightvar(--van-line-height-md)页码行高--van-image-preview-index-text-shadow0 1px 1px var(--van-gray-8)页码文字阴影--van-image-preview-overlay-backgroundrgba(0, 0, 0, 0.9)遮罩层背景--van-image-preview-close-icon-size22px关闭图标大小--van-image-preview-close-icon-colorvar(--van-gray-5)关闭图标颜色--van-image-preview-close-icon-marginvar(--van-padding-md)关闭图标边距--van-image-preview-close-icon-z-index1关闭图标层级:root { --van-image-preview-overlay-background: rgba(0, 0, 0, 0.85); --van-image-preview-close-icon-size: 24px; }从样式文件还可看到.van-image-preview容器为全屏position: fixed布局--van-image-preview-close-icon-*四组边距变量分别对应关闭图标的top-left、top-right、bottom-left、bottom-right四个位置修饰符。常见问题在桌面端无法操作组件ImagePreview 基于触摸事件touchstart/touchmove/touchend实现手势桌面端浏览器默认不支持触摸事件需按桌面端适配章节的说明引入vant-touch-emulator进行适配对应仓库 packages/vant-touch-emulator。引用 showImagePreview 时出现编译报错如果引用showImagePreview方法时出现以下报错说明项目中使用了babel-plugin-import插件导致代码被错误编译These dependencies were not found: * vant/es/show-image-preview in ./src/xxx.js * vant/es/show-image-preview/style in ./src/xxx.jsVant 从 4.0 版本开始不再支持babel-plugin-import插件请参考迁移指南移除该插件同样适用于本组件所在的全部按需引入场景改用 unplugin-vue-components 等现代按需引入方案。小结ImagePreview 是 Vant 中交互最复杂的组件之一对外提供函数调用 组件调用双模式 API内部则完整实现了轮播切换、单击/双击/捏合/长按手势、长图适配、异步关闭拦截与 CSS 变量主题定制。结合本文提供的源码路径ImagePreview.tsx、ImagePreviewItem.tsx、function-call.tsx与测试用例你可以进一步深入其实现细节或在自定义image插槽的基础上扩展出视频预览、富文本预览等业务能力。【免费下载链接】vantA lightweight, customizable Vue UI library for mobile web apps.项目地址: https://gitcode.com/GitHub_Trending/va/vant创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表