Upload
概述
Upload文件上传组件,支持单文件/多文件上传、拖拽上传、上传进度显示、图片/视频预览与文件删除。上传通过与服务器约定的上传API完成,上传结果经解析后写入状态,默认只保留文件url。
示例
声明一个上传字段需要指定widget: 'upload'并通过url提供上传接口地址:
const form = document.querySelector('#form');
form.state = {
file: configurable('', {
label: '文件',
widget: 'upload',
url: 'api/upload',
}),
};指南
文件上传 API
服务器需要部署一个接收文件的API(例如:/api/upload),用于接收上传的文件,并返回处理结果。
url用于指定该上传地址,例如/api/upload。
fileFieldName用于指定上传请求中文件的表单字段名称,默认是files。以express为例,当上传文件时,可以通过req.body.files读取到文件内容。
约定文件上传API应该返回:
type SchemaUploadWidgetFile = {
url: string;
id?: string;
title?: string;
size?: number;
};url: 上传文件后的网址,可以用于预览。id: 可选的文件唯一标识,如果您在数据库中保存文件上传记录,一般可以返回对应的 id。此值在删除时提供。title: 可选的、友好名称,用于显示。size: 可选的,实际上传大小。
删除文件
单击删除按钮时会调用onRemove回调,可以在此向服务器发起删除请求,返回Promise后文件才真正被移除:
form.state = {
files: configurable([], {
label: '文件',
widget: 'upload',
onRemove: async (file) => {
// 在此向服务器发起删除请求
await fetch(`api/upload?id=${file.id}`, { method: 'DELETE' });
},
}),
};上传数量
支持上传一个文件或多个文件:
form.state = {
// 上传多个文件(默认)
files: configurable([], {
label: '文件',
widget: 'upload',
multiple: true,
}),
// 只上传单个文件
file: configurable('', {
label: '文件',
widget: 'upload',
multiple: false,
}),
};解析上传响应
onResolve用于对上传文件API的响应进行解析。
一般情况下,我们约定服务器上部署的上传API应返回SchemaUploadWidgetFile。在旧项目或其他因素下,返回的不是SchemaUploadWidgetFile时,则需要使用onResolve将返回内容解析为SchemaUploadWidgetFile。
比如:当POST http://myserver.com/upload文件时,返回的是:
{
file: 'images/a.png';
}需要转换为SchemaUploadWidgetFile:
form.state = {
files: configurable([], {
label: '文件',
widget: 'upload',
onResolve: (response) => {
response.url = response.file;
return response;
},
}),
};限制文件类型
fileTypes参数用于限制上传的文件类型,可以接受 MIME 类型和文件扩展名,参考accept参数:
form.state = {
files: configurable([], {
label: '文件',
widget: 'upload',
fileTypes: [
'.jpg',
'.png',
'image/*',
'video/*',
'audio/*',
],
}),
};预览
preview用于控制是否显示文件预览,特别是上传图片时:
true: 显示默认的预览元素,一般只对图片和视频文件有效false: 不预览,只显示文件标题或url
form.state = {
files: configurable([], {
label: '相片',
widget: 'upload',
preview: false,
}),
};提示
单击图片时可以放大预览显示。
文件选择器
selector用于控制如何选择文件:
auto: 默认,单选时只显示上传按钮,多选时显示接收文件的矩形区域button: 显示一个上传选择文件按钮,单击后选择文件rectangle: 显示一个接收文件的矩形区域,单击后选择文件或拖动文件到此上传
form.state = {
files: configurable([], {
label: '文件',
widget: 'upload',
selector: 'button',
}),
};保存上传数据
默认情况下,上传字段只保存上传文件的url:
- 当上传
abc.jpg到api/upload时,服务器将文件保存在upload/abc.jpg, - 然后服务器返回
{url:'upload/abc.jpg', size:12984, id:'da1412f3', title:'我的头像'}(如果不是则应该使用onResolve进行解析转换), - 再将
url写入状态中。即此时form.state.file === 'upload/abc.jpg'。
也就是说,在状态中只保留了上传文件的url。
有时,我们需要在数据中保存更多的信息,包括文件大小、id、title等。这时可以配置onlyFileUrl=false,则将整个SchemaUploadWidgetFile写入状态,因此form.state.file === {url:'upload/abc.jpg', size:12984, id:'da1412f3', title:'我的头像'}:
form.state = {
file: configurable(
{ url: '' },
{
label: '文件',
widget: 'upload',
onlyFileUrl: false,
},
),
};属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
url | string | '' | 上传接口地址 |
fileTypes | array | [] | 允许的文件类型(MIME 或扩展名,"*"通配) |
multiple | boolean | true | 是否多文件上传 |
fileFieldName | string | "files" | 上传请求中文件的表单字段名 |
preview | boolean | true | 是否显示文件预览 |
tips | string | 拖动文件到此处或点击选择文件上传 | 上传区域提示文字 |
selector | string | "auto" | 选择器形态:auto / button / rectangle |
onResolve | function | 内置 | 上传结果解析:从响应中解析出文件列表 |
onFileLabel | function | 内置 | 文件显示名生成,默认取title或url末段文件名 |
onRemove | function | 删除文件回调,可在此调用服务器删除接口,返回Promise后才真正移除 | |
onlyFileUrl | boolean | true | 值只保留文件url;false时保留完整文件对象 |
注意事项
- 上传是逐文件发起的
FormData请求,文件字段名由fileFieldName决定,服务器需要按此字段读取文件。 - 默认的响应解析要求返回值为字符串(只含
url)或含url字段的对象,不符合约定时必须提供onResolve。 - 单文件字段(
multiple=false)建议初值用''或{url:''};多文件字段初值用数组。 onRemove返回Promise后文件才会从列表中移除,可以在其中先完成服务器删除再resolve。