doc.md 13.9 KB
Newer Older
L
liuyijun 已提交
1 2 3 4 5 6 7 8
# Uploader 上传

### 介绍

用于将本地的图片或文件上传至服务器。

### 安装

9
``` ts
L
liuyijun 已提交
10
import { Uploader } from '@nutui/nutui-react';
L
liuyijun 已提交
11 12 13
```
### 基本用法

14
:::demo
L
liuyijun 已提交
15
``` tsx
16 17 18 19 20 21 22 23 24 25 26
import React, { useState } from "react";
import { Uploader } from '@nutui/nutui-react';

const App = () => {
  const uploadUrl = 'https://my-json-server.typicode.com/linrufeng/demo/posts'
  const onStart = () => {
    console.log('start 触发')
  }
  return (
    <>
      <h2>基础用法</h2>
27 28 29 30 31 32 33 34 35 36 37 38 39
      <Uploader
        url={uploadUrl}
        onStart={onStart}
        style={{ marginRight: '10px' }}
      />
      <Uploader
        url={uploadUrl}
        uploadIconSize="20px"
        uploadIconTip="商品主图"
        onStart={onStart}
        style={{ marginRight: '10px' }}
      />
      <Uploader url={uploadUrl} uploadIcon="dongdong" onStart={onStart} />
40 41 42 43
    </>
  )
}
export default App;
L
liuyijun 已提交
44
```
J
junjun666 已提交
45
:::
L
liuyijun 已提交
46

47 48 49 50 51 52 53 54 55 56
### 上传状态

:::demo
``` tsx
import React, { useState } from "react";
import { Uploader } from '@nutui/nutui-react';

const App = () => {
  const uploadUrl = 'https://my-json-server.typicode.com/linrufeng/demo/posts'
  const defaultFileList: FileType<string>[] = [
57 58 59 60 61 62 63 64
    {
      name: '文件文件文件1.png',
      url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
      status: 'success',
      message: '上传成功',
      type: 'image',
      uid: '123',
    },
65 66 67 68 69 70 71 72 73
    {
      name: '文件1.png',
      url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
      status: 'success',
      message: '上传成功',
      type: 'image',
      uid: '123',
    },
    {
74
      name: '文件4.png',
75 76 77 78 79
      url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
      status: 'error',
      message: '上传失败',
      type: 'image',
      uid: '124',
80
      errorIcon: 'star',
81 82
    },
    {
83
      name: '文件4.png',
84 85
      url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
      status: 'uploading',
86
      message: '上传中',
87 88 89
      type: 'image',
      uid: '125',
    },
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
    {
      name: '文件4.png',
      url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
      status: 'uploading',
      message: '上传中',
      type: 'image',
      uid: '125',
      loadingIcon: 'loading1',
    },
    {
      name: '文件4.png',
      url: 'https://m.360buyimg.com/babel/jfs/t1/164410/22/25162/93384/616eac6cE6c711350/0cac53c1b82e1b05.gif',
      status: 'uploading',
      message: '上传中',
      type: 'image',
      uid: '125',
      loadingIcon: ' ',
    },
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
  ]
  const onDelete = (file: FileItem, fileList: FileItem[]) => {
    console.log(translated.ca3903f3, file, fileList)
  }
  return (
    <>
      <h2>上传状态</h2>
      <Uploader
        url={uploadUrl}
        defaultFileList={defaultFileList}
        onRemove={onDelete}
        uploadIcon="dongdong"
      />
    </>
  )
}
export default App;
```
:::

L
liuyijun 已提交
128 129
### 自定义上传样式

J
junjun666 已提交
130
:::demo
L
liuyijun 已提交
131
``` tsx
132 133 134 135 136 137 138 139 140
import React, { useState } from "react";
import { Uploader, Button } from '@nutui/nutui-react';

const App = () => {
  const uploadUrl = 'https://my-json-server.typicode.com/linrufeng/demo/posts'
  return (
    <>
      <h2>自定义上传样式</h2>
      <Uploader url={uploadUrl}>
141
        <Button type="success" size="small">
142 143 144 145 146 147 148
          上传文件
        </Button>
      </Uploader>
    </>
  )
}
export default App;
L
liuyijun 已提交
149
```
J
junjun666 已提交
150
:::
L
liuyijun 已提交
151

152
### 自定义上传使用默认进度条
J
junjun666 已提交
153 154

:::demo
L
liuyijun 已提交
155
``` tsx
156
import React, { useState } from "react";
157
import { Uploader, Button, Progress } from '@nutui/nutui-react';
158 159 160

const App = () => {
  const uploadUrl = 'https://my-json-server.typicode.com/linrufeng/demo/posts'
161 162 163 164
  const [progressPercent, setProgressPercent] = useState(0)
  const onProgress = ({ event, options, percentage }: any) => {
    setProgressPercent(percentage)
  }
165 166
  return (
    <>
167 168 169 170 171 172 173 174 175 176 177 178
      <h2>自定义上传使用默认进度条</h2>
      <Uploader url={uploadUrl} onProgress={onProgress}>
        <Button type="success" size="small">
          上传文件
        </Button>
      </Uploader>
      <br />
      <Progress
        percentage={progressPercent}
        strokeColor="linear-gradient(270deg, rgba(18,126,255,1) 0%,rgba(32,147,255,1) 32.815625%,rgba(13,242,204,1) 100%)"
        status
      />
179 180 181 182
    </>
  )
}
export default App;
L
liuyijun 已提交
183
```
J
junjun666 已提交
184
:::
L
liuyijun 已提交
185

186
### 直接调起摄像头(移动端生效)
J
junjun666 已提交
187 188

:::demo
L
liuyijun 已提交
189
``` tsx
190 191 192 193 194 195 196
import React, { useState } from "react";
import { Uploader, Button } from '@nutui/nutui-react';

const App = () => {
  const uploadUrl = 'https://my-json-server.typicode.com/linrufeng/demo/posts'
  return (
    <>
197 198
      <h2>直接调起摄像头(移动端生效)</h2>
      <Uploader capture url={uploadUrl} />
199 200 201 202
    </>
  )
}
export default App;
L
liuyijun 已提交
203
```
J
junjun666 已提交
204
:::
205 206

### 限制上传数量5个
L
liuyijun 已提交
207

J
junjun666 已提交
208
:::demo
L
liuyijun 已提交
209
``` tsx
210 211 212 213 214 215 216 217
import React, { useState } from "react";
import { Uploader, Button } from '@nutui/nutui-react';

const App = () => {
  const uploadUrl = 'https://my-json-server.typicode.com/linrufeng/demo/posts'
  return (
    <>
      <h2>限制上传数量5个</h2>
O
oasis-cloud 已提交
218
      <Uploader url={uploadUrl} multiple maximum="5" />
219 220 221 222
    </>
  )
}
export default App;
L
liuyijun 已提交
223
```
J
junjun666 已提交
224 225
:::

226
### 限制上传大小(每个文件最大不超过 50kb)
L
liuyijun 已提交
227

J
junjun666 已提交
228
:::demo
229 230 231 232 233 234 235 236 237 238 239 240
``` tsx
import React, { useState } from "react";
import { Uploader, Button } from '@nutui/nutui-react';

const App = () => {
  const uploadUrl = 'https://my-json-server.typicode.com/linrufeng/demo/posts'
  const onOversize = (files: File[]) => {
    console.log('oversize 触发 文件大小不能超过 50kb', files)
  }
  return (
    <>
      <h2>限制上传大小(每个文件最大不超过 50kb)</h2>
O
oasis-cloud 已提交
241
      <Uploader url={uploadUrl} multiple maximize={1024 * 50} oversize={onOversize} />
242 243
    </>
  )
L
liuyijun 已提交
244
}
245
export default App;
L
liuyijun 已提交
246
```
J
junjun666 已提交
247
:::
L
liuyijun 已提交
248

249

L
liuyijun 已提交
250 251
### 自定义 FormData headers

J
junjun666 已提交
252
:::demo
L
liuyijun 已提交
253
``` tsx
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
import React, { useState } from "react";
import { Uploader, Button } from '@nutui/nutui-react';

const App = () => {
  const uploadUrl = 'https://my-json-server.typicode.com/linrufeng/demo/posts'
  const formData = {
    custom: 'test',
  }
  return (
    <>
      <h2>自定义 FormData headers</h2>
      <Uploader
        url={uploadUrl}
        data={formData}
        headers={formData}
O
oasis-cloud 已提交
269 270
        withCredentials
       />
271 272 273 274
    </>
  )
}
export default App;
L
liuyijun 已提交
275
```
J
junjun666 已提交
276
:::
L
liuyijun 已提交
277

278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
### 自定义 xhr 上传方式(before-xhr-upload)

:::demo
``` tsx
import React, { useState } from "react";
import { Uploader, Button } from '@nutui/nutui-react';

const App = () => {
  const uploadUrl = 'https://my-json-server.typicode.com/linrufeng/demo/posts'
  const beforeXhrUpload = (xhr: XMLHttpRequest, options: any) => {
    if (options.method.toLowerCase() == 'put') {
      xhr.send(options.sourceFile);
    } else {
      xhr.send(options.formData);
    }
  };
  return (
    <>
      <h2>自定义 xhr 上传方式(before-xhr-upload)</h2>
      <Uploader
        url={uploadUrl}
        method="put"
        onBeforeXhrUpload={beforeXhrUpload}
       />
    </>
  )
}
export default App;
```
:::

309 310
### 手动上传

J
junjun666 已提交
311
:::demo
312 313 314 315 316 317 318 319 320 321 322 323 324
``` tsx
import React, { useState, useRef } from "react";
import { Uploader, Button } from '@nutui/nutui-react';

const App = () => {
  const uploadUrl = 'https://my-json-server.typicode.com/linrufeng/demo/posts'
  const uploadRef = useRef(null)
  const submitUpload = () => {
    uploadRef.current.submit()
  }
  return (
    <>
      <h2>手动上传</h2>
O
oasis-cloud 已提交
325
      <Uploader url={uploadUrl} maximum="5" autoUpload={false} ref={uploadRef} />
326 327 328 329 330 331
      <br />
      <Button type="success" size="small" onClick={submitUpload}>
        执行上传
      </Button>
    </>
  )
L
liuyijun 已提交
332
}
333
export default App;
L
liuyijun 已提交
334
```
J
junjun666 已提交
335
:::
L
liuyijun 已提交
336 337 338

### 禁用状态

J
junjun666 已提交
339
:::demo
L
liuyijun 已提交
340
``` tsx
341 342 343 344 345 346 347
import React, { useState } from "react";
import { Uploader, Button } from '@nutui/nutui-react';

const App = () => {
  return (
    <>
      <h2>禁用状态</h2>
O
oasis-cloud 已提交
348
      <Uploader disabled />
349 350 351 352
    </>
  )
}
export default App;
L
liuyijun 已提交
353
```
J
junjun666 已提交
354
:::
L
liuyijun 已提交
355 356 357

### Prop

358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388
| 字段| 说明| 类型| 默认值|
|---------|------|--------|----------|
| autoUpload `v1.3.4`| 是否在选取文件后立即进行上传,false 时需要手动执行 ref submit 方法进行上传| Boolean| true           |
| name| `input` 标签 `name` 的名称,发到后台的文件参数名| String| "file"|
| url| 上传服务器的接口地址| String                            | -|
| defaultFileList| 默认已经上传的文件列表| FileItem[]| []                |
| isPreview| 是否上传成功后展示预览图| Boolean                           | true|
| defaultImg| 当上传非图片('image')格式的默认图片地址| String| ''             |
| isDeletable| 是否展示删除按钮| Boolean| true|
| method| 上传请求的 http method| String| "post"           |
| listType `v1.3.4`| 上传列表的内建样式,支持两种基本样式 picture、list| String| "picture"|
| capture| 图片[选取模式](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/input#htmlattrdefcapture),直接调起摄像头| String| false            |
| maximize| 可以设定最大上传文件的大小(字节)| Number丨String| Number.MAX_VALUE |
| maximum| 文件上传数量限制| Number丨String| 1|
| clearInput       | 是否需要清空`input`内容,设为`true`支持重复选择上传同一个文件| Boolean| true            |
| accept            | 允许上传的文件类型,[详细说明](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/Input/file#%E9%99%90%E5%88%B6%E5%85%81%E8%AE%B8%E7%9A%84%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B) | String| *|
| headers           | 设置上传的请求头部| Object| {}|
| data| 附加上传的信息 formData| Object| {}|
| uploadIcon| 上传区域[图标名称](#/zh-CN/icon)或图片链接| String| "photograph"|
| uploadIconSize `v1.3.4`| 上传区域[图标尺寸](#/icon)大小,如 `20px` `2em` `2rem`| String or Number| -     |
| uploadIconTip`v1.4.9`| 上传区域图片下方文字| String| ""|
| xhrState| 接口响应的成功状态(status)值| Number| 200|
| withCredentials  | 支持发送 cookie 凭证信息| Boolean| false|
| multiple| 是否支持文件多选| Boolean| false|
| disabled| 是否禁用文件上传| Boolean| false|
| timeout| 超时时间,单位为毫秒| Number丨String| 1000 * 30|
| beforeUpload `v1.3.4 废弃`| 上传前的函数需要返回一个`Promise`对象| Function| null|
| onBeforeUpload `v1.3.4`| 上传前的函数需要返回一个`Promise`对象| Function| null|
| onBeforeXhrUpload `v1.3.4`     | 执行 XHR 上传时,自定义方式| Function(xhr,option)| null|
| beforeDelete  `v1.3.4 废弃`   | 除文件时的回调,返回值为 false 时不移除。支持返回一个 `Promise` 对象,`Promise` 对象 resolve(false) 或 reject 时不移除| Function(file): boolean 丨Promise | -                |
| onBeforeDelete  `v1.3.4`  | 除文件时的回调,返回值为 false 时不移除。支持返回一个 `Promise` 对象,`Promise` 对象 resolve(false) 或 reject 时不移除| Function(file): boolean 丨Promise | -|
L
liuyijun 已提交
389 390 391 392


### FileItem

393 394 395 396 397 398 399 400
| 名称     | 说明| 默认值|
|----------|-------------|-------------|
| status   | 文件状态值,可选'ready,uploading,success,error,removed' | "ready"|
| uid      | 文件的唯一标识| new Date().getTime().toString() |
| name     | 文件名称| ""|
| url      | 文件路径| ""|
| type     | 文件类型| "image/jpeg"|
| formData | 上传所需的data| new FormData()|
L
liuyijun 已提交
401 402 403 404 405

### Event

| 名称     | 说明                   | 回调参数             |
|----------|------------------------|----------------------|
406
| start `v1.3.4 `    | 文件上传开始           | options              |
407
| onStart `v1.3.4`    | 文件上传开始           | options              |
408
| progress `v1.3.4 废弃` | 文件上传的进度         | event,options        |
409
| onProgress `v1.3.4` | 文件上传的进度         | event,options,percentage        |
410
| oversize `v1.3.4 废弃` | 文件大小超过限制时触发 | files                |
411
| onOversize `v1.3.4` | 文件大小超过限制时触发 | files                |
412
| success `v1.3.4 废弃`  | 上传成功               | responseText,options |
413
| onSuccess `v1.3.4`  | 上传成功               | responseText,options |
414
| failure `v1.3.4 废弃`  | 上传失败               | responseText,options |
415 416
| onFailure `v1.3.4`  | 上传失败               | responseText,options |
| onChange `v1.3.4`   | 上传文件改变时的状态   | fileList,event       |
417
| change `v1.3.4 废弃`  | 上传文件改变时的状态   | fileList,event       |
418
| onRemove `v1.3.4`   | 文件删除之前的状态     | files,fileList       |
419
| removeImage  `v1.3.4 废弃` | 文件删除之前的状态     | files,fileList       |
420
| onFileItemClick `v1.3.4`   | 文件上传成功后点击触发     | fileItem       |
L
liuyijun 已提交
421

422 423 424 425 426 427 428 429 430 431 432

## 主题定制

### 样式变量

组件提供了下列 CSS 变量,可用于自定义样式,使用方法请参考 [ConfigProvider 组件](#/zh-CN/component/configprovider)

| 名称 | 默认值 |
| --- | --- |
| --nutui-uploader-picture-width | ` 100px` |
| --nutui-uploader-picture-height | ` 100px` |
433 434
| --nutui-uploader-picture-border`v1.4.9` | ` 0px` |
| --nutui-uploader-picture-border-radius`v1.4.9` | ` 4px` |
435
| --nutui-uploader-background | ` $gray4` |
436 437 438 439 440 441 442 443 444 445 446 447 448 449
| --nutui-uploader-background-disabled`v1.4.9` | ` $gray4` |
| --nutui-uploader-picture-icon-opacity`v1.4.9` | ` 0.7` |
| --nutui-uploader-picture-icon-opacity-disabled`v1.4.9` | ` 0.3`|
| --nutui-uploader-picture-icon-margin-bottom`v1.4.9` | ` 6px`|
| --nutui-uploader-picture-icon-tip-font-size`v1.4.9` | ` 12px`|
| --nutui-uploader-picture-icon-tip-color`v1.4.9` | ` #BFBFBF`|
| --nutui-uploader-preview-progress-background`v1.4.9` | ` rgba(0, 0, 0, 0.65)`|
| --nutui-uploader-preview-margin-right`v1.4.9` | ` 10px`|
| --nutui-uploader-preview-margin-bottom`v1.4.9` | ` 10px`|
| --nutui-uploader-preview-tips-height`v1.4.9` | ` 24px`|
| --nutui-uploader-preview-tips-background`v1.4.9` | ` rgba(0, 0, 0, 0.45)`|
| --nutui-uploader-preview-tips-padding`v1.4.9` | ` 0 5px`|
| --nutui-uploader-preview-close-right`v1.4.9` | ` 0px`|
| --nutui-uploader-preview-close-top`v1.4.9` | ` 0px`|