useFile
信息
新版本的useFile新增了相关事件的参数配置. 但和小程序中的事件略有出入. 由于taro-hooks采用的是Promise的方式编写. 这边事件名称分别见
useFile
上传、下载文件
何时使用
当需要上传下载文件时
API
const { download, upload } = useFile();
返回值说明
返回值 | 说明 | 类型 |
---|---|---|
download | 下载文件 | PromiseAction<DownloadOption, Taro.downloadFile.FileSuccessCallbackResult> |
upload | 上传文件 | PromiseAction<UploadOption, Taro.uploadFile.SuccessCallbackResult> |
DownloadOption
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
url | 下载资源的 url | string | - |
filePath | 指定文件下载后存储的路径 | string | - |
header | HTTP 请求的 Header,Header 中不能设置 Referer | TaroGeneral.IAnyObject | - |
progress | 监听下载进度变化事件 | DownloadTask['onProgressUpdate'] | - |
headersReceive | 监听 HTTP Response Header 事件。会比请求完成事件更早 | DownloadTask['onHeadersReceived'] | - |
afterSend | 实例后挂载对应监听方法 | (task: DownloadTask.DownloadTaskPromise) => void | - |
UploadOption
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
url | 开发者服务器地址 | string | - |
filePath | 要上传文件资源的路径 | string | - |
name | 文件对应的 key,开发者在服务端可以通过这个 key 获取文件的二进制内容 | string | - |
formData | HTTP 请求中其他额外的 form data | TaroGeneral.IAnyObject | - |
timeout | 超时时间,单位为毫秒 | number | - |
header | HTTP 请求的 Header,Header 中不能设置 Referer | TaroGeneral.IAnyObject | - |
fileName | 上传的文件名, API 支持度: h5 | string | - |
progress | 监听下载进度变化事件 | UploadTask['onProgressUpdate'] | - |
headersReceive | 监听 HTTP Response Header 事件。会比请求完成事件更早 | UploadTask['onHeadersReceived'] | - |
afterSend | 实例后挂载对应监听方法 | (task: UploadTask.UploadTaskPromise) => void | - |
代码演示
- React
- Vue
network/useFile/index
import React from 'react';
import { showToast, showModal, chooseVideo } from '@tarojs/taro';
import { useState } from '@taro-hooks/core';
import { log, logError } from '@taro-hooks/shared';
import { useFile } from 'taro-hooks';
import DemoContent from '@src/components/DemoContent';
import { Cell, Button, Progress, Input, Field } from '@taroify/core';
export default () => {
const [loading, setLoading] = useState<boolean>(false);
const [uploadProgress, setUploadProgress] = useState<number>(0);
const [downloadFile, setDownloadFile] = useState<string>(
'https://storage.360buyimg.com/nutui/video/video_NutUI.mp4',
);
const [downloadProgress, setDownloadProgress] = useState<number>(0);
const { download, upload } = useFile();
const onProgress = (
{ progress = 0, totalBytesSent = 0, totalBytesExpectedToSend = 0 } = {},
action,
) => {
action(progress);
showToast({
title: '${progress}%: ${totalBytesSent} / ${totalBytesExpectedToSend}',
icon: 'loading',
mask: true,
});
};
const onHeadersReceived = (headers) => {
log(headers);
showToast({
title: 'onHeadersReceived trigger',
icon: 'none',
mask: true,
});
};
const handleDownload = async () => {
if (!downloadFile?.length) return;
const downloadUpdate = (progressResult) =>
onProgress(progressResult, setDownloadProgress);
const option = {
progress: downloadUpdate,
headersReceive: onHeadersReceived,
url: downloadFile,
};
setLoading(true);
setDownloadProgress(0);
try {
const response = await download(option);
showModal({
title: '下载成功',
content: response?.tempFilePath,
showCancel: false,
});
} catch (e) {
logError(e.message);
}
setLoading(false);
};
const handleUpload = async () => {
try {
const videos = await chooseVideo({});
if (videos?.tempFilePath) {
setUploadProgress(0);
setLoading(true);
const uploadUpdate = (progressResult) =>
onProgress(progressResult, setUploadProgress);
const option = {
progress: uploadUpdate,
headersReceive: onHeadersReceived,
filePath: videos.tempFilePath,
};
const response = await upload(option);
showModal({
title: '上传成功',
content: response?.data,
showCancel: false,
});
}
} catch (e) {
logError(e.message);
}
setLoading(false);
};
return (
<DemoContent>
<Cell title="上传" clickable>
<Button loading={loading} onClick={handleUpload}>
点击
</Button>
</Cell>
<Progress percent={uploadProgress} />
<Field label="地址">
<Input
value={downloadFile}
onChange={(event) => setDownloadFile(event.detail.value)}
placeholder="请输入下载地址"
/>
</Field>
<Cell title="下载" clickable>
<Button loading={loading} onClick={handleDownload}>
点击
</Button>
</Cell>
<Progress percent={downloadProgress} />
</DemoContent>
);
};
network/useFile/index
<template>
<demo-content>
<nut-cell title="上传">
<template v-slot:link>
<nut-button @click="handleUpload()">点击</nut-button>
</template>
</nut-cell>
<nut-progress :percentage="uploadProgress" />
<nut-input
label="地址"
placeholder="请输入下载地址"
v-model="downloadFile"
@update:model-value="setDownloadFile($event)"
/>
<nut-cell title="下载">
<template v-slot:link>
<nut-button :loading="loading" @click="handleDownload()"
>点击</nut-button
>
</template>
</nut-cell>
<nut-progress :percentage="downloadProgress" />
</demo-content>
</template>
<script setup lang="ts">
import { showToast, showModal, chooseVideo } from '@tarojs/taro';
import { useState } from '@taro-hooks/core';
import { escapeState, log, logError } from '@taro-hooks/shared';
import { useFile } from 'taro-hooks';
const [loading, setLoading] = useState<boolean>(false);
const [uploadProgress, setUploadProgress] = useState<number>(0);
const [downloadFile, setDownloadFile] = useState<string>(
'https://storage.360buyimg.com/nutui/video/video_NutUI.mp4',
);
const [downloadProgress, setDownloadProgress] = useState<number>(0);
const { download, upload } = useFile();
const onProgress = (
{ progress = 0, totalBytesSent = 0, totalBytesExpectedToSend = 0 } = {},
action,
) => {
action(progress);
showToast({
title: '${progress}%: ${totalBytesSent} / ${totalBytesExpectedToSend}',
icon: 'loading',
mask: true,
});
};
const onHeadersReceived = (headers) => {
log(headers);
showToast({
title: 'onHeadersReceived trigger',
icon: 'none',
mask: true,
});
};
const handleDownload = async () => {
if (!escapeState(downloadFile)?.length) return;
const downloadUpdate = (progressResult) =>
onProgress(progressResult, setDownloadProgress);
const option = {
progress: downloadUpdate,
headersReceive: onHeadersReceived,
url: escapeState(downloadFile),
};
setLoading(true);
setDownloadProgress(0);
try {
const response = await download(option);
showModal({
title: '下载成功',
content: response?.tempFilePath,
showCancel: false,
});
} catch (e) {
logError(e.message);
}
setLoading(false);
};
const handleUpload = async () => {
try {
const videos = await chooseVideo({});
if (videos?.tempFilePath) {
setUploadProgress(0);
setLoading(true);
const uploadUpdate = (progressResult) =>
onProgress(progressResult, setUploadProgress);
const option = {
progress: uploadUpdate,
headersReceive: onHeadersReceived,
filePath: videos.tempFilePath,
};
const response = await upload(option);
showModal({
title: '上传成功',
content: response?.data,
showCancel: false,
});
}
} catch (e) {
logError(e.message);
}
setLoading(false);
};
</script>
Hook 支持度
微信小程序 | H5 | ReactNative |
---|---|---|
✔️ | ✔️ | ✔️ |
FAQ
如何abort下载或上传?
可以使用afterSend监听方法获取到xxxTask.xxxTaskPromise.
import { useRef } from '@tarojs/taro';
const task = useRef<UploadTask.UploadTaskPromise>();
const afterSend = (concurrentTask) => (task.current = concurrentTask);
// then
task.current.abort();