更新记录

1.0.0(2026-10-09) 下载此版本

首个版本:把「任意视图内容导出为图片」的能力封装成可复用的组件与工具方法。

新增

  • 组件 <yolo-export>:包裹任意内容即可导出为图片
    • 方法:exportImage() / saveToAlbum() / download() / toTempFilePath() / capture()
    • props:file-name、pixel-ratio、background-color、skip-fonts、skip-selector、skip-local-file、lib-path、fallback-lib-path、toast
    • 事件:start / success / fail
  • js_sdk/save-image.js 工具:saveImageToAlbum、saveBase64Image、downloadBase64Image、readLocalImageAsDataUrl 等
  • 截图:主库 html-to-image(SVG foreignObject,App/H5 通用),备用 html2canvas(可关闭)
  • 保存相册四级兜底:隐藏 canvas 中转 → plus Bitmap → FileSystemManager → base64 直存

踩坑记录(均已内置处理)

  • 鸿蒙端 renderjs 的 callMethod 只传第一个参数 → 回传统一用单个对象 { data, reason, w, h }
  • 鸿蒙端不能用 uni.getImageInfo 解析 dataURL 取尺寸(报 File name too long)→ 尺寸由 renderjs 按「节点尺寸 × 倍率」回传
  • 隐藏 canvas 尺寸为 0 时 drawImage 抛 InvalidStateError → 占位尺寸 + 节点尺寸校验
  • 安卓/iOS 的 file:// 下本地图片会污染画布(Tainted canvases)→ 默认跳过本地图节点,并提供 readLocalImageAsDataUrl 内联方案
  • App 的 file:// 下远程图标字体必然被 CORS 拦截 → skipFonts 跳过字体内嵌,减少无效请求与报错

平台兼容性

uni-app(3.8.5)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
× √ √ √ √ × √ √ √
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
× × × × × × × × × - × ×

yolo-export 视图截图导出

把任意视图内容截成图片并导出:用 <yolo-export> 包裹要导出的内容,通过 ref 调方法即可拿到图片(base64 / 临时文件路径)、保存到相册或下载。

不绑定任何业务 —— 分享卡片、海报、报表、票据、二维码等场景都能复用。

平台支持

平台 支持 说明
App(Android / iOS) √ 主路径 canvas 中转;另有 plus / FileSystemManager / base64 直存兜底
App(鸿蒙) √ 仅 canvas 中转可用(鸿蒙无 plus、无 uni.env),插件已内置该路径
H5 √ 直接下载 PNG
小程序 × 未适配(渲染层与 App/H5 差异大,需要另一套 canvas 方案)
uni-app x × 未适配

鸿蒙端 createCanvasContext / canvasToTempFilePath 需要 HBuilderX 4.23+。

快速开始

<template>
  <yolo-export
    ref="exporter"
    file-name="share-card"
    @start="saving = true"
    @success="saving = false"
    @fail="saving = false"
  >
    <!-- 这里的内容会被整块截图 -->
    <view class="card">
      <text>任意内容</text>
    </view>
  </yolo-export>

  <button :loading="saving" @click="onSave">保存到相册</button>
</template>

<script setup>
import { ref } from 'vue'
import YoloExport from '@/uni_modules/yolo-export/components/yolo-export/yolo-export.vue'

const exporter = ref(null)
const saving = ref(false)

async function onSave() {
  // exportImage():App 存相册 / H5 下载,最常用
  await exporter.value.exportImage()
}
</script>

组件注册方式(二选一)

  1. 显式 import(推荐):如上,标签写 <YoloExport> 或 <yolo-export>,任何时候都可靠
  2. easycom 自动注册:符合 uni_modules/<插件id>/components/<组件名>/<组件名>.vue 结构, 无需 import 即可用 <yolo-export>,前提是 pages.json 的 easycom.autoscan 为 true

⚠️ HBuilderX 的 easycom 组件清单在启动时扫描一次:项目运行中新增 uni_modules 插件, 本次运行可能仍报 Failed to resolve component: yolo-export,重启运行即可。 想省掉这类时机问题,直接用方式 1。

组件方法(通过 ref 调用)

方法 说明 返回
exportImage(options?) 自动:App 存相册 / H5 下载 { base64, fileName, width, height, tempFilePath?, via? }
saveToAlbum(options?) App 存相册(H5 会降级为下载) 同上
download(options?) H5 浏览器下载(App 端会降级为存相册) 同上
toTempFilePath(options?) App:截图落成临时文件,可用于上传 { tempFilePath, ... }
capture(options?) 只截图,拿 dataURL(全端) { base64, width, height }

options 可覆盖组件 props:{ fileName, timeout }(超时默认 15 秒)。方法均返回 Promise,失败时 reject 并带中文原因。

组件 props

属性 类型 默认值 说明
file-name String export 导出文件名(不含后缀,按图片类型自动补)
pixel-ratio Number 3 截图倍率,越大越清晰、体积越大(建议 1~4)
background-color String #ffffff 截图背景色,透明区域会填充该色
skip-fonts Boolean true 跳过 Web 字体内嵌(远程图标字体在 App 的 file:// 下必被 CORS 拦,跳过可少一堆报错)
skip-selector String - 截图时额外排除的节点(CSS 选择器,逗号分隔),如 .no-export
skip-local-file Boolean null 是否跳过引用本地文件的图片节点。null = 自动:安卓/iOS 跳过,鸿蒙/H5 保留(原因见下)
lib-path String 插件内置 主截图库地址,一般不用改
fallback-lib-path String 插件内置 备用库(html2canvas);传 none 可关闭以少加载 190KB
toast Boolean true 是否使用内置系统提示(宿主有自己的交互时可关掉)

组件事件

事件 参数 说明
@start { mode } 开始导出(可用来开按钮 loading)
@success { base64, fileName, tempFilePath?, via? } 导出成功;via 记录实际走通的保存通道,便于排障
@fail { mode, message } 导出失败,message 为中文原因

工具方法(js_sdk/save-image.js)

不依赖组件,可直接 import 使用:

import {
  saveImageToAlbum,      // { base64 | filePath, fileName } → 相册,多通道降级
  saveBase64Image,       // { base64, fileName } → 本地临时文件路径
  downloadBase64Image,   // base64 → 浏览器下载(H5)
  readLocalImageAsDataUrl, // '/static/xxx.png' → dataURL
  writeBase64ToFile,     // base64 → 本地文件(Android/iOS)
  stripBase64Prefix,     // 去掉 data:image/...;base64, 前缀
  withExt,               // 按 mime 补文件名后缀
  hasPlus,               // 当前是否具备 plus 能力
  isWeb,                 // 当前是否 H5
} from '@/uni_modules/yolo-export/js_sdk/save-image.js'

常见问题

1. 安卓导出失败:「画布可能被图片污染 / Tainted canvases」

安卓(以及 iOS)的页面源是 file://,把本地文件图片画进 canvas 会让画布变成 tainted,导出时 toDataURL 直接抛 SecurityError。

两种处理方式:

  • 推荐:导出前把本地图转成 dataURL(无跨源属性,双端都安全)

    import { readLocalImageAsDataUrl } from '@/uni_modules/yolo-export/js_sdk/save-image.js'
    
    const logoSrc = ref('/static/images/logo.png')
    readLocalImageAsDataUrl('/static/images/logo.png')
    .then(uri => { if (uri) logoSrc.value = uri })
    .catch(() => { /* 失败就沿用静态路径 */ })
    <yolo-export>
    <image :src="logoSrc" />
    </yolo-export>
  • 兜底:插件默认(skip-local-file 为 null)在安卓/iOS 自动跳过这类图片节点 —— 少一张图,但整张导出不会失败。鸿蒙与 H5 不受影响,本地图照常渲染。

2. 鸿蒙端导出很慢或一直转圈

鸿蒙走的是「隐藏 canvas 中转」:截图 → drawImage 到离屏 canvas → canvasToTempFilePath → 保存相册。中间会有一次系统相册授权弹窗(约数秒),属正常现象。

3. 组件内容没变却被截了旧图 / 打开就自动截图

组件内部用 shotPayload.key 自增触发 renderjs,用完即归零。若你自己 fork 了组件代码,请保留这一机制(key 不归零时,内容重建会被当成新值再截一次)。

4. 截图里图标/字体变成方框

skip-fonts 会跳过字体内嵌,远程图标字体(如 //at.alicdn.com/...)在 App 的 file:// 下本来就加载不到。如需图标出现在导出图里,建议改用图片/SVG 图标,或把字体文件下载到本地静态目录后引入。

5. 内容尺寸为 0 时导出失败

组件会先校验节点尺寸,为 0 时报「导出节点尺寸为 0,请确认内容已渲染」。常见于内容在 v-if 内尚未渲染、或父容器 display:none 时触发导出。

目录结构

yolo-export/
├─ components/yolo-export/yolo-export.vue   # 导出组件(含 renderjs 截图模块)
├─ js_sdk/save-image.js                     # 通用图片工具(存相册/下载/本地图转 dataURL)
├─ static/js/html-to-image.js               # 主截图库(19KB)
├─ static/js/html2canvas.min.js             # 备用截图库(194KB,可关闭)
├─ changelog.md
└─ package.json

隐私、权限声明

1. 本插件需要申请的系统权限列表:

保存到相册(相册写入权限由宿主 App 声明)

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

许可协议

MIT协议

暂无用户评论。