项目
版本

Uppy 核心

Uppy 可以作为一个具有众多功能的上传器和界面。功能可以通过插件递增添加,但 Uppy 可以根据你的需求尽可能地精简。因此,我们构建了 Uppy 的核心,@uppy/core,作为一个独立的协调器。它充当状态管理器、事件发射器和限制处理器。

何时应该使用它?

@uppy/core 是 Uppy 生态系统的基石,是所有添加插件的协调者。无论你寻找的是哪种上传体验,一切都从安装这个插件开始。

你可以使用 @uppy/core构建自己的 UI 或选择使用 Dashboard 集成。对于上传插件,你可以参考 选择你需要的上传器

如果你想看看这一切是如何结合在一起的,请查看 示例

安装

  • npm

    npm install @uppy/core
    
  • yarn

    yarn add @uppy/core
    
  • CDN

    <!-- 1. Add CSS to `<head>` -->
    <link
      href="https://releases.transloadit.com/uppy/v3.27.3/uppy.min.css"
      rel="stylesheet"
    />
    
    <!-- 2. Initialize -->
    <div id="uppy"></div>
    
    <script type="module">
      import { Uppy } from "https://releases.transloadit.com/uppy/v3.27.3/uppy.min.mjs";
      const uppy = new Uppy();
    </script>
    

使用

@uppy/core 有四个导出:UppyUIPluginBasePlugindebugLogger。默认导出是 Uppy 类。

使用 Uppy 文件

Uppy 使用浏览器的 File API 在状态中保存文件,但它被包装在 Object 中以便能够向其添加更多数据,我们称之为Uppy 文件。所有这些属性对插件和副作用(如 事件 )都非常有用。

修改这些属性应通过 方法 进行。

Uppy 文件属性

file.source

负责添加此文件的插件的名称。通常是像 'GoogleDrive' 这样的远程提供程序插件或像 'DragDrop' 这样的 UI 插件。

file.id

文件的唯一 ID。

file.name

文件的名称。

file.meta

包含每个文件的标准以及用户定义元数据的对象。任何自定义文件元数据都应该是可 JSON 序列化的。以下标准元数据将存储在所有文件对象上,但插件可能会添加更多元数据。

  • file.meta.name
    • file.name 相同。

  • file.meta.type
    • file.type 相同。

  • file.meta.relativePath
    • 对于任何通过拖放或在 Uppy 中打开的本地文件夹,文件夹内的文件将具有 relativePath 元数据字段设置为其相对于文件夹的路径。relativePath 以文件夹的名称开始并以文件的名称结束。如果直接拖放或打开文件,relativePath 将为 null。远程(提供程序)文件也存在相同的行为,但路径将是相对于用户的选中项(复选框)的。没有前导或尾随斜杠。

    • 本地文件示例: 当拖放名为 folder1 的本地文件夹时,该文件夹内有一个名为 folder2 的文件夹,而 folder2 内有一个名为 file 的文件,该文件的 relativePath 元数据字段将为 folder1/folder2/file。然而,如果直接拖放或打开 filerelativePath 将为 null

    • 远程文件示例: 假设我们有一个远程提供程序文件结构,如 /folder1/folder2/file。然后,如果用户勾选了 folder1 旁边的复选框,filerelativePath 将是 "folder1/folder2/file"。但是,如果用户首先导航到 folder1,然后才勾选 folder2 旁边的复选框,relativePath 将是 "folder2/file"

  • file.meta.absolutePath
    • absolutePath 元数据字段仅对远程文件设置。无论用户选择如何,它始终相对于提供程序文件列表的根目录,即用户所见的那样。absolutePath 总是以 / 开头,并且始终以文件名结束。澄清:absolutePathrelativePath 之间的区别在于,absolutePath 仅存在于远程文件中,并且总是拥有文件的完整路径,而 relativePath 是相对于用户所选文件夹的文件路径。

file.type

文件的 MIME 类型。如果用户浏览器未提供文件类型,这实际上可能是猜测的,因此这是一个尽力而为的值,并不能保证完全正确。

file.data

对于本地文件,这是代表文件内容的实际 FileBlob 对象。 对于从远程提供程序导入的文件,文件数据在浏览器中不可用。

file.progress

包含上传进度数据的对象。
属性

  • bytesUploaded - 到目前为止已上传的字节数。
  • bytesTotal - 必须总共上传的字节数。
  • uploadStarted - 如果上传尚未开始,则为 null。一旦开始,此属性将存储一个 UNIX 时间戳。请注意,这仅在预处理后设置。
  • uploadComplete - 表示上传是否完成的布尔值。注意,这并不意味着后处理也已完成。
  • percentage - 介于 0 和 100 之间的整数百分比。

file.size

file.size 文件大小,单位为字节。

file.isRemote

布尔值:此文件是否从远程提供商导入?

file.remote

用于远程提供商的数据包。通常对终端用户不太有趣。

file.preview

文件的可选视觉缩略图的 URL 。

file.uploadURL

上传完成后,这可能包含上传文件的 URL 。 根据服务器配置,它可能无法访问或不正确。

new Uppy(options?)

import Uppy from '@uppy/core';

const uppy = new Uppy();

选项

id

实例在整个站点范围内的唯一 ID(string,默认值:uppy)。

如果使用了多个 Uppy 实例,例如,在两个不同的页面上,应指定一个 id 。这使得 Uppy 能够在不与其他 Uppy 实例冲突的情况下在 localStorage 中存储信息 。
此 ID 应在页面重载和导航时保持持久性——不应该每次加载 Uppy 时都是一个随机数,每次都不相同。

autoProceed

一旦添加文件立即开始上传(boolean,默认值:false)。

默认情况下,Uppy 将在 UI 中按下上传按钮或调用 .upload() 方法后才开始上传。将此设置为 true 将在选择第一个文件后自动开始上传

allowMultipleUploadBatches

是否允许多个上传批次(boolean,默认值:true)。

这意味着多次调用 .upload() ,或者用户在已经上传一些之后添加更多文件的。一个上传批次由自上次调用 .upload() 以来添加的文件组成。

将此选项设置为 true ,用户可以上传一些文件,然后添加更多文件并同样上传。一个模型用例是将图片上传到画廊或向电子邮件添加附件。

将此选项设置为 false ,用户可以上传一些文件,并且您可以监听 'complete' 事件以继续应用程序的下一步上传流程。一个典型的用例是上传新的头像。如果您正在与现有 HTML 表单集成,此选项提供了最接近于裸露 <input type="file"> 的行为 。

debug

是否发送调试和警告日志( boolean,默认值: false )。

将此设置为 true 会将 logger 设置为 debugLogger

logger

用于 uppy.log 的日志记录器( Object,默认: justErrorsLogger )。

通过提供您自己的logger,您可以将调试信息发送到服务器,选择仅记录错误等。

logger 设置为 debugLogger 以将调试信息输出到浏览器控制台:

您也可以提供自己的日志记录器对象:它应该公开 debugwarnerror 方法,如下面的例子所示。
这是一个什么都不做的 logger 示例:

const nullLogger = {
  debug: (...args) => {},
  warn: (...args) => {},
  error: (...args) => {},
};

restrictions

限制上传的条件( Object ,默认值: {} )。

属性 描述
maxFileSize number 每个单独文件的最大文件大小(字节)
minFileSize number 每个单独文件的最小文件大小(字节)
maxTotalFileSize number 所有可选上传文件的总最大文件大小(字节)
maxNumberOfFiles number 可以选择的文件总数
minNumberOfFiles number 必须在上传前选择的文件最小数量
allowedFileTypes Array 通配符 image/* ,或确切的 MIME 类型 image/jpeg ,或文件扩展名 .jpg['image/*', '.jpg', '.jpeg', '.png', '.gif']
requiredMetaFields Array<string> 要求每个文件的 meta 对象中的键在上传之前必须存在

meta

附加到每个文件元数据的键/值对 ( Object,默认: {} )。

还存在两个用于更新 metadata 的方法:setMetasetFileMeta

元数据也可以通过页面上的 <form> 元素、使用 Form 插件或在使用 Dashboard 及 metaFields 选项时通过 UI 来添加。

onBeforeFileAdded(file, files)

在文件被添加到 Uppy 之前调用的函数( Function,默认: (files, file) => !Object.hasOwn(files, file.id) )。

使用此函数对所选文件进行任意数量的自定义检查,或对其进行操作,例如优化文件名。您也可以允许重复文件。

您可以返回 true 以保持文件不变,false 以移除文件,或返回修改后的文件。

默认情况下,不会向用户显示关于文件未通过验证的通知。我们建议使用 uppy.info() 显示消息给用户,并通过 uppy.log() 记录到控制台以供调试。

过滤、更改和中断示例

允许所有文件,包括重复文件。这将在文件未被上传时替换文件。如果再次上传重复文件,处理方式取决于您的上传插件和后端。

const uppy = new Uppy({
  // ...
  onBeforeFileAdded: () => true,

仅保留满足条件的文件:

const uppy = new Uppy({
 // ...
 onBeforeFileAdded: (currentFile, files) => {
   if (currentFile.name === 'forest-IMG_0616.jpg') {
     return true
   }
   return false
 },

更改所有文件名:

const uppy = new Uppy({
  // ...
  onBeforeFileAdded: (currentFile, files) => {
    const modifiedFile = {
      ...currentFile,
      name: `${currentFile.name}__${Date.now()}`,
    }
    return modifiedFile
  },

中断文件上传:

const uppy = new Uppy({
  // ...
  onBeforeFileAdded: (currentFile, files) => {
    if (!currentFile.type) {
      // 输出到控制台
      uppy.log(`跳过文件因为它没有类型`);
      // 向用户显示错误消息
      uppy.info(`跳过文件因为它没有类型`, "error", 500);
      return false;
    }
  },
});

onBeforeUpload(files)

在上传开始前调用的函数(Function,默认:(files) => files)。

使用此函数检查所有文件或它们的总数是否符合您的要求,或在上传前一次性操纵所有文件。

您可以返回 true 继续上传,false 取消上传,或返回修改后的文件。

默认情况下,不会向用户显示关于文件未通过验证的通知。我们建议使用 uppy.info() 显示消息给用户,并通过 uppy.log() 记录到控制台以供调试。

更改和中断示例

更改所有文件名:

const uppy = new Uppy({
  // ...
  onBeforeUpload: (files) => {
    // 我们将小心地返回新对象,而不是修改原始`files`
    const updatedFiles = {};
    Object.keys(files).forEach((fileID) => {
      updatedFiles[fileID] = {
        ...files[fileID],
        name: `${myCustomPrefix}__${files[fileID].name}`,
      };
    });
    return updatedFiles;
  },
});

中断上传:

const uppy = new Uppy({
  // ...
  onBeforeUpload: (files) => {
    if (Object.keys(files).length < 2) {
      // 输出到控制台
      uppy.log(`由于仅选择了 ${Object.keys(files).length} 个文件,中断上传`);
      // 向用户显示错误消息
      uppy.info(`您至少需要选择 2 个文件`, "error", 500);
      return false;
    }
    return true;
  },
});

locale

您可以通过传递包含要覆盖键的 strings 对象来覆盖区域设置字符串。

如果您需要其他语言,最好使用 地区设置

module.exports = {
  strings: {
    addBulkFilesFailed: {
      0: "由于内部错误,未能添加 %{smart_count} 个文件",
      1: "由于内部错误,未能添加 %{smart_count} 个文件",
    },
    youCanOnlyUploadX: {
      0: "您只能上传 %{smart_count} 个文件",
      1: "您只能上传 %{smart_count} 个文件",
    },
    youHaveToAtLeastSelectX: {
      0: "您至少需要选择 %{smart_count} 个文件",
      1: "您至少需要选择 %{smart_count} 个文件",
    },
    exceedsSize: "%{file} 超过了允许的最大大小 %{size}",
    missingRequiredMetaField: "缺少必需的元数据字段",
    missingRequiredMetaFieldOnFile: "在 %{fileName} 中缺少必需的元数据字段",
    inferiorSize: "此文件小于允许的大小 %{size}",
    youCanOnlyUploadFileTypes: "您只能上传: %{types}",
    noMoreFilesAllowed: "无法添加更多文件",
    noDuplicates: "无法添加重复文件 '%{fileName}', 它已存在",
    companionError: "与 Companion 的连接失败",
    authAborted: "认证中止",
    companionUnauthorizeHint: "要取消授权您的 %{provider} 账户,请访问 %{url}",
    failedToUpload: "上传 %{file} 失败",
    noInternetConnection: "没有互联网连接",
    connectedToInternet: "已连接到互联网",
    // 远程提供商的字符串
    noFilesFound: "您在此处没有文件或文件夹",
    selectX: {
      0: "选择 %{smart_count}",
      1: "选择 %{smart_count}",
    },
    allFilesFromFolderNamed: "来自文件夹 %{name} 的所有文件",
    openFolderNamed: "打开文件夹 %{name}",
    cancel: "取消",
    logOut: "注销",
    filter: "过滤",
    resetFilter: "重置过滤器",
    loading: "加载中...",
    authenticateWithTitle: "请使用 %{pluginName} 进行身份验证以选择文件",
    authenticateWith: "连接到 %{pluginName}",
    signInWithGoogle: "使用 Google 登录",
    searchImages: "搜索图片",
    enterTextToSearch: "输入文本以搜索图片",
    search: "搜索",
    emptyFolderAdded: "未从空文件夹添加任何文件",
    folderAlreadyAdded: '文件夹 "%{folder}" 已经添加',
    folderAdded: {
      0: "从 %{folder} 添加了 %{smart_count} 个文件",
      1: "从 %{folder} 添加了 %{smart_count} 个文件",
    },
  },
};

store

用于跟踪内部状态的存储 ( Object,默认:DefaultStore )。

此选项可用于将 Uppy 状态插入外部状态管理库,如 Redux

infoTimeout

Informer 通知可见的时间长度 (number,默认:5000) 。

方法

use(plugin, opts)

向 Uppy 添加插件,并可选地提供插件选项对象。

import Uppy from "@uppy/core";
import DragDrop from "@uppy/drag-drop";

const uppy = new Uppy();
uppy.use(DragDrop, { target: "body" });

removePlugin(instance)

卸载并移除插件。

getPlugin(id)

通过其 id 获取插件以访问其方法。

getID()

获取 Uppy 实例 ID,请参阅 id 选项。

addFile(file)

将新文件添加到 Uppy 的内部状态。addFile 将返回添加的文件生成的 id。

如果文件无法添加,addFile 会给出错误,原因可能是 onBeforeFileAdded(file) 抛出了错误,或者 uppy.opts.restrictions 检查失败。

uppy.addFile({
  name: "my-file.jpg", // 文件名
  type: "image/jpeg", // 文件类型
  data: blob, // 文件 Blob
  meta: {
    // 可选,存储文件的目录路径,以便 Uppy 可以区分不同目录中的相同文件。
    relativePath: webkitFileSystemEntry.relativePath,
  },
  source: "Local", // 可选,确定文件的来源,例如 Instagram。
  isRemote: false, // 可选,如果实际文件不在浏览器中,而是在某个远程服务器上,请设置为 true,例如,
  // 当与 companion 一起使用时搭配 Instagram。
});

查看 如何处理 Uppy 文件

如果 uppy.opts.autoProceed === true ,当有文件被添加时,Uppy 将会自动开始上传。

有时你可能需要向 Uppy 中添加远程文件。这可以通过 获取文件然后创建 Blob 对象实现,或者使用 Url 插件配合 Companion来实现。

有时你可能需要标记某些文件为 “已上传”,以便用户看到它们,但实际上它们不会被 Uppy 再次上传。这可以通过 遍历文件并设置 uploadComplete: true, uploadStarted: true 在它们身上来实现 。

removeFile(fileID)

从 Uppy 中移除一个文件。移除正在上传的文件会取消那个上传过程。

uppy.removeFile("uppyteamkongjpg1501851828779");

clearUploadedFiles()

清除状态。在成功上传后手动重置 Uppy 时可能会用到。

上传插件可能会在上传过程中被调用时抛出错误。

getFile(fileID)

通过其 ID 获取特定的 Uppy 文件

const file = uppy.getFile("uppyteamkongjpg1501851828779");

getFiles()

获取所有已添加的 Uppy 文件 数组 。

const files = uppy.getFiles();

upload()

开始上传已添加的文件。

返回一个 Promise result,解析后包含两个数组,分别表示已上传的文件:

  • result.successful - 成功上传的文件。
  • result.failed - 未成功上传的文件。这些文件将具有描述问题的 .error 属性。
uppy.upload().then((result) => {
  console.info("成功的上传:", result.successful);

  if (result.failed.length > 0) {
    console.error("错误:");
    result.failed.forEach((file) => {
      console.error(file.error);
    });
  }
});

pauseResume(fileID)

在上传上切换暂停/恢复。仅当使用可恢复上传插件,如 Tus 时有效。

pauseAll()

暂停所有上传。仅当使用可恢复上传插件,如 Tus 时有效。

resumeAll()

恢复所有上传。仅当使用可恢复上传插件,如 Tus 时有效。

retryUpload(fileID)

重试一个上传(例如,在错误之后)。

retryAll()

重试所有上传(例如,在错误之后)。

cancelAll({ reason: 'user' })

参数 类型 描述
reason string 取消的原因。插件可以使用此来提供不同的清理行为(Transloadit 插件会在用户点击“取消”按钮时取消 Assembly)。可能的值有:user(默认)- 用户已按下 “取消” ;unmount - Uppy 实例已被程序关闭

取消所有上传,重置进度并移除所有文件。

setState(patch)

更新 Uppy 的内部状态。通常,这个方法在内部被调用,但在某些情况下,直接更改某些内容可能很有用,尤其是在实现自定义插件时。

Uppy 初始化时的默认状态:

const state = {
  plugins: {},
  files: {},
  currentUploads: {},
  capabilities: {
    resumableUploads: false,
  },
  totalProgress: 0,
  meta: { ...this.opts.meta },
  info: {
    isHidden: true,
    type: "info",
    message: "",
  },
};

更新状态:

uppy.setState({ smth: true });

getState()

返回来自 Store 的当前状态。

setFileState(fileID, state)

更新单个文件的状态。这对于可能希望在 Uppy 文件 上存储数据,或需要将文件特定配置传递给其他支持此功能的插件的插件特别有用。

fileID 是字符串形式的文件 ID。state 是一个对象,它将被合并到文件的状态对象中。

setMeta(data)

更改状态中的全局 meta 对象,该对象可以在 Uppy 选项中设置,并与所有新添加的文件合并。调用 setMeta 还会将新添加的元数据与之前选定的文件合并。

uppy.setMeta({ resize: 1500, token: "ab5kjfg" });

setFileMeta(fileID, data)

更新特定文件的元数据。

uppy.setFileMeta("myfileID", { resize: 1500 });

setOptions(opts)

更改 Uppy 初始化时使用的选项。

const uppy = new Uppy();

uppy.setOptions({
  restrictions: { maxNumberOfFiles: 3 },
  autoProceed: true,
});

uppy.setOptions({
  locale: {
    strings: {
      cancel: "取消",
    },
  },
});

您也可以为插件更改选项:

// 动态改变 Dashboard 拖放区域的宽度
uppy.getPlugin("Dashboard").setOptions({
  width: 300,
});

close({ reason: 'user' })

参数 类型 描述
reason string 取消的原因。插件可以使用此来提供不同的清理行为(例如,Transloadit 插件在用户点击“取消”按钮时会取消 Assembly)。可能的值有:user(默认)- 用户已按下 “取消” ;unmount - Uppy 实例已被程序关闭

卸载所有插件并关闭此 Uppy 实例。在此之前也会运行 uppy.cancelAll()

logout()

对每个远程提供商插件(如 Google Drive、Instagram 等)调用 provider.logout() 。例如,在您的应用中用户注销账户后,这也将清理与 Uppy 云提供商的连接,以增强安全性。

log(message, type)

参数 类型 描述
message string 要记录的消息
type string? debugwarnerror

更多详情请参阅 logger 文档。

uppy.log("[Dashboard] 正在添加文件...");

info(message, type, duration)

在状态中设置一个可由通知 UI 插件显示的消息,可选详细信息。它使用了默认包含在 Dashboard 中的 Informer 插件。

参数 类型 描述
message string, Object '信息提示'{ message: '哦,不!', details: '文件无法上传' }
type string? 'info''warning''success''error'
duration number? 毫秒数

当此信息消息应显示或隐藏时,会触发 info-visibleinfo-hidden 事件。

this.info("哦,好事发生了!", "success", 3000);
this.info(
  {
    message: "哦,不,坏事发生了!",
    details: "文件无法上传,因为没有网络连接",
  },
  "error",
  5000
);

addPreProcessor(fn)

添加一个预处理函数。fn 在上传开始前会接收到文件 ID 列表。fn 应该返回一个 Promise。其解析值将被忽略。

要更改文件数据等,请使用 Uppy 状态更新,例如使用 setFileState

addUploader(fn)

添加一个上传器函数。fn 在应该开始上传时会接收到文件 ID 列表。上传器函数应执行实际的上传工作,比如创建并发送 XMLHttpRequest 或调用某些上传服务 SDK。fn 应该返回一个 Promise,当所有文件都被上传完毕后,这个 Promise 会解析。

addPostProcessor(fn)

添加一个后处理函数。fn 在上传完成后会接收到文件 ID 列表。fn 应该返回一个 Promise,当处理工作完成时解析。Promise 的值将被忽略。

例如,您可以等待文件编码或 CDN 传播完成,或者您可以进行 HTTP API 调用来创建一个包含所有已上传图像的相册。

removePreProcessor/removeUploader/removePostProcessor(fn)

移除处理器或上传器函数

从 Uppy 中移除之前添加的处理器或上传器功能。通常,这应该在 uninstall() 方法中完成。

on('event', action)

订阅 Uppy 事件。下面列出了所有事件的完整列表。

once('event', action)

创建一个只触发一次的事件监听器。下面列出了所有事件的完整列表。

off('event', action)

取消订阅 Uppy 事件。下面列出了所有事件的完整列表。

事件

Uppy 公开了一系列可以订阅以产生副作用的事件。

file-added

每当有文件被添加时触发。

参数

uppy.on("file-added", (file) => {
  console.log("添加了文件", file);
});

files-added

参数

  • files - 一次性添加(批处理)的 Uppy 文件 数组。

当有一个或多个文件被添加时触发——一个事件,代表所有文件。

file-removed

每当有文件被移除时触发。

参数

  • file - 被移除的 Uppy 文件
  • reason - 解释文件为什么被移除的字符串。详情见 #2301 。当前的原因包括:removed-by-usercancel-all

示例

uppy.on('file-removed', (file, reason) => {
	console.log('移除了文件', file);
});

uppy.on('file-removed', (file, reason) => {
	从上传计数器UI中移除文件(file);

	if (reason === 'removed-by-user') {
		为文件(file)发送删除请求;
	}
});

upload

当上传开始时触发。

uppy.on("upload", (data) => {
  // data 对象包含有 `id`(上传ID)和 `fileIDs`(当前上传中的文件ID数组)
  // data: { id, fileIDs }
  console.log(`开始上传 ${id} 对于文件 ${fileIDs}`);
});

preprocess-progress

预处理器的进度。

参数

progress 是一个对象,具有以下属性:

  • mode - 可能是 'determinate''indeterminate'
  • message - 显示给用户的提示信息。如 '正在准备上传...',尽可能具体。

mode'determinate' 时,还需添加 value 属性:

  • value - 介于 0 和 1 之间的进度值。

progress

每次总上传进度更新时触发:

参数

  • progress - 表示总上传进度的整数(0-100)。

示例

uppy.on("progress", (progress) => {
  // progress: 总进度百分比
  console.log(progress);
});

upload-progress

每当单个文件上传进度可用时触发:

参数

  • file - 进度更新的 Uppy 文件
  • progress - 与 file.progress 中相同的对象。

示例

uppy.on("upload-progress", (file, progress) => {
  // file: { id, name, type, ... }
  // progress: { uploader, bytesUploaded, bytesTotal }
  console.log(file.id, progress.bytesUploaded, progress.bytesTotal);
});

postprocess-progress

后处理器的进度。

参数

progress 是一个对象,具有以下属性:

  • mode - 可能是 'determinate''indeterminate'
  • message - 显示给用户的提示信息。如 '正在准备上传...',尽可能具体。

mode'determinate' 时,还需添加 value 属性:

  • value - 介于 0 和 1 之间的进度值。

upload-success

每当单个上传完成时触发。

参数

  • file - 被上传的 Uppy 文件
  • response - 包含来自远程端点的响应数据的对象。实际内容取决于所使用的上传插件 。

对于 @uppy/xhr-upload,形状如下:

{
	"status": 200, // HTTP状态码(0、200、300等)
	"body": "…", // 响应体
	"uploadURL": "…" // 如果返回了文件URL
}

示例

uppy.on("upload-success", (file, response) => {
  console.log(file.name, response.uploadURL);
  const img = new Image();
  img.width = 300;
  img.alt = file.id;
  img.src = response.uploadURL;
  document.body.appendChild(img);
});

complete

当所有上传完成时触发。

result 参数是一个对象,包含 successfulfailed 文件数组,类似于 uppy.upload() 的返回值。

uppy.on("complete", (result) => {
  console.log("成功文件:", result.successful);
  console.log("失败文件:", result.failed);
});

error

当 Uppy 无法上传或编码整个上传时触发。

参数

  • error - 错误对象。

示例

uppy.on("error", (error) => {
  console.error(error.stack);
});

upload-error

每次单个上传失败时触发。

参数

  • file - 未上传成功的 Uppy 文件
  • error - 错误对象。
  • response - 可选参数,包含来自上传端点的响应数据。

根据使用的上传插件,它可能未定义或包含不同数据。

对于 @uppy/xhr-upload,形状如下:

{
  "status": 200, // HTTP状态码(0、200、300等)
  "body": "…" // 响应体
}

示例

uppy.on("upload-error", (file, error, response) => {
  console.log("文件错误:", file.id);
  console.log("错误信息:", error);
});

如果错误与网络条件有关——例如,由于防火墙或 ISP 阻止导致端点不可达——错误对象将具有 error.isNetworkError 属性设置为 true。检查网络错误的方法如下:

uppy.on("upload-error", (file, error, response) => {
  if (error.isNetworkError) {
    // 让用户知道文件上传可能因防火墙或ISP问题而失败
    alertUserAboutPossibleFirewallOrISPIssues(error);
  }
});

upload-retry

当上传被重试(例如,在错误之后)时触发。

参数

  • fileID - 正在被重试的文件 ID。

示例

uppy.on("upload-retry", (fileID) => {
  console.log("上传重试:", fileID);
});

upload-stalled

当上传在一段时间内没有收到任何进度(在 @uppy/xhr-upload 中,延迟由 timeout 选项定义)时触发。使用此事件在 UI 上显示消息,告诉用户他们可能需要重试上传。

uppy.on("upload-stalled", (error, files) => {
  console.log("上传似乎停滞", error, files);
  const noLongerStalledEventHandler = (file) => {
    if (files.includes(file)) {
      console.log("上传不再停滞");
      uppy.off("upload-progress", noLongerStalledEventHandler);
    }
  };
  uppy.on("upload-progress", noLongerStalledEventHandler);
});

retry-all

当所有失败的上传被重试时触发。

参数

  • fileIDs - 数组,包含被重试的文件 ID。

示例

uppy.on("retry-all", (fileIDs) => {
  console.log("上传重试:", fileIDs);
});

info-visible

当 “info” 消息应显示在用户界面中时触发。默认情况下,Informer 插件会显示这些消息(在 Dashboard 插件中默认启用)。你可以利用此事件在自定义 UI 中显示消息:

uppy.on('info-visible', () => {
	const { info } = uppy.getState();
	// info: {
	//   isHidden: false,
	//   type: 'error',
	//   message: '上传失败',
	//   details: '错误描述'
	// }
	console.log(`${info.message} ${info.details}`);
});

info-hidden

当“info”消息应隐藏在用户界面中时触发。参见 info-visible

cancel-all

参数 类型 描述
reason string 参见 uppy.cancelAll

当调用 cancelAll() ,所有上传被取消,文件被移除,进度被重置时触发。

restriction-failed

当添加的文件违反了某些限制时触发。此事件为希望自定义文件上传限制行为的人提供了另一种选择。

uppy.on("restriction-failed", (file, error) => {
  // 执行一些自定义逻辑,如向用户显示系统通知
});

reset-progress

当调用resetProgress(),每个文件的上传进度都被重置为零时触发。

uppy.on("reset-progress", () => {
  // 进度已被重置
});

new BasePlugin(uppy, options?)

构建插件的基础构造块。

BasePlugin 不包含 DOM 渲染,因此可用于没有用户界面的插件 。

有关于 Preact 渲染接口的扩展版本,请参见 UIPlugin

查看 构建插件 指南。

选项

传递给 BasePlugin 的选项是你希望在插件中支持的所有选项。

你应该在插件类的构造函数中将选项传递给 super

class MyPlugin extends BasePlugin {
  constructor(uppy, opts) {
    super(uppy, opts);
  }
}

方法

setOptions(options)

初始化时传入的选项也可以通过 setOptions 动态更改。

getPluginState()

Uppy 类中检索插件状态。Uppy 在状态中保持一个 plugins 对象,其中每个键是插件的 id ,值是它的状态。

setPluginState()

Uppy 类中设置插件状态。Uppy 在状态中保持一个 plugins 对象,其中每个键是插件的 id ,值是它的状态。

install()

install 方法在插件使用 .use() 被添加到 Uppy 时运行一次。在此处初始化插件。

例如,如果你正在创建一个预处理器(如 @uppy/compressor ),你需要添加它:

install () {
  this.uppy.addPreProcessor(this.prepareUpload)
}

另一个常见的做法是,当你创建一个 UI 插件 时,将其 挂载 到 DOM 上:

install () {
  const { target } = this.opts
  if (target) {
    this.mount(target, this)
  }
}

uninstall()

uninstall 方法在插件从 Uppy 中移除时运行一次。这发生在调用 .close() 或在框架集成中销毁插件时 。

在此清理事物。

例如,当你创建一个预处理器、上传器或后处理器时,要移除它:

uninstall () {
  this.uppy.removePreProcessor(this.prepareUpload)
}

在创建 UI 插件 时,你也应该 卸载 它从 DOM 上:

卸载方法

uninstall () {
  this.unmount()
}

i18nInit

在插件类的构造函数中调用 this.i18nInit() 一次,以初始化 国际化

addTarget

您可以使用此方法使您的插件成为其他插件的 target。这是 @uppy/dashboard 用来向其用户界面添加其他插件的方式。

update

在每次状态更新时被调用。您很少需要使用这个,除非您想使用除 Preact 之外的其他工具来构建用户界面插件。

afterUpdate

在每次状态更新后带有防抖处理调用,此时所有内容都已挂载完毕。

new UIPlugin(uppy, options?)

UIPlugin 扩展了 BasePlugin 以添加使用 Preact 的渲染功能。当您想要创建用户界面或对其进行补充(如 Dashboard )时,请使用此方法。

参见 BasePlugin 了解所有插件的初始构建模块。

查看 构建插件 指南。

选项

传递给 UIPlugin 的选项是您希望在插件中支持的所有选项。

您应该在插件类中将这些选项传递给 super

class MyPlugin extends UIPlugin {
  constructor(uppy, opts) {
    super(uppy, opts);
  }
}

反过来,这些也会传递给底层的 BasePlugin

方法

BasePlugin 继承的所有方法也进入了 UIPlugin

mount(target)

将此插件挂载到 target 元素上。target 可以是 CSS 查询选择器、DOM 元素或另一个插件。如果 target 是一个插件,源(当前)插件将在目标插件中注册,后者可以决定如何和在哪里渲染源插件。

onMount()

在 Preact 渲染完插件的组件后被调用。

unmount

从 DOM 中移除插件。通常您不需要覆盖它,但应从 uninstall 中调用它。

默认值是:

unmount () {
  if (this.isTargetDOMEl) {
    this.el?.remove()
  }
  this.onUnmount()
}

onUnmount()

在元素从 DOM 中移除后被调用。可用于清理或其他副作用。

render()

渲染插件的用户界面。Uppy 使用 Preact 作为其视图引擎,因此 render() 应返回一个 Preact 元素。render 会由 Uppy 在每次状态变化时自动调用。

update(state)

在每次状态更新时被调用。您很少需要使用这个,除非您想使用除 Preact 之外的其他工具来构建用户界面插件。

debugLogger()

开发期间提供额外调试和警告日志的记录器。

import { Uppy, debugLogger } from "@uppy/core";

new Uppy({ logger: debugLogger });

您也可以通过设置 debugtrue 来启用此记录器。

logger 的默认值是 justErrorsLogger,看起来像这样:

// 吞噬所有日志,除了错误。
// 如果未设置 logger 或 debug: false,则为默认值
const justErrorsLogger = {
  debug: () => {},
  warn: () => {},
  error: (...args) => console.error(`[Uppy] [${getTimeStamp()}]`, ...args),
};

debugLogger 发送额外的调试和警告日志,这在开发期间可能有帮助:

// 带有命名空间 + 时间戳打印到控制台的日志,
// 由 logger: Uppy.debugLogger 或 debug: true 设置
const debugLogger = {
  debug: (...args) => console.debug(`[Uppy] [${getTimeStamp()}]`, ...args),
  warn: (...args) => console.warn(`[Uppy] [${getTimeStamp()}]`, ...args),
  error: (...args) => console.error(`[Uppy] [${getTimeStamp()}]`, ...args),
};

常见问题解答

如何允许重复文件?

您可以使用 onBeforeFileAdded 允许所有文件,甚至是重复文件。这将会覆盖尚未上传的文件。如果您再次上传重复文件,具体处理方式取决于您的上传插件和后端。

const uppy = new Uppy({
  // ...
  onBeforeFileAdded: () => true,
在本文档中