用于將本地的圖片或文件上傳至服務(wù)器,并在上傳過程中展示預(yù)覽圖和上傳進(jìn)度。目前 Uploader 組件不包含將文件上傳至服務(wù)器的接口邏輯,該步驟需要自行實(shí)現(xiàn)。
通過以下方式來全局注冊(cè)組件,更多注冊(cè)方式請(qǐng)參考組件注冊(cè)。
import { createApp } from 'vue';
import { Uploader } from 'vant';
const app = createApp();
app.use(Uploader);
文件上傳完畢后會(huì)觸發(fā) after-read 回調(diào)函數(shù),獲取到對(duì)應(yīng)的 file 對(duì)象。
<van-uploader :after-read="afterRead" />
export default {
setup() {
const afterRead = (file) => {
// 此時(shí)可以自行將文件上傳至服務(wù)器
console.log(file);
};
return {
afterRead,
};
},
};
通過 v-model 可以綁定已經(jīng)上傳的文件列表,并展示文件列表的預(yù)覽圖。
<van-uploader v-model="fileList" multiple />
import { ref } from 'vue';
export default {
setup() {
const fileList = ref([
{ url: 'https://img.yzcdn.cn/vant/leaf.jpg' },
// Uploader 根據(jù)文件后綴來判斷是否為圖片文件
// 如果圖片 URL 中不包含類型信息,可以添加 isImage 標(biāo)記來聲明
{ url: 'https://cloud-image', isImage: true },
]);
return {
fileList,
};
},
};
通過 status 屬性可以標(biāo)識(shí)上傳狀態(tài),uploading 表示上傳中,failed 表示上傳失敗,done 表示上傳完成。
<van-uploader v-model="fileList" :after-read="afterRead" />
import { ref } from 'vue';
export default {
setup() {
const fileList = ref([
{
url: 'https://img.yzcdn.cn/vant/leaf.jpg',
status: 'uploading',
message: '上傳中...',
},
{
url: 'https://img.yzcdn.cn/vant/tree.jpg',
status: 'failed',
message: '上傳失敗',
},
]);
const afterRead = (file) => {
file.status = 'uploading';
file.message = '上傳中...';
setTimeout(() => {
file.status = 'failed';
file.message = '上傳失敗';
}, 1000);
};
return {
fileList,
afterRead,
};
},
};
通過 max-count 屬性可以限制上傳文件的數(shù)量,上傳數(shù)量達(dá)到限制后,會(huì)自動(dòng)隱藏上傳區(qū)域。
<van-uploader v-model="fileList" multiple :max-count="2" />
import { ref } from 'vue';
export default {
setup() {
const fileList = ref([]);
return {
fileList,
};
},
};
通過 max-size 屬性可以限制上傳文件的大小,超過大小的文件會(huì)被自動(dòng)過濾,這些文件信息可以通過 oversize 事件獲取。
<van-uploader multiple :max-size="500 * 1024" @oversize="onOversize" />
import { Toast } from 'vant';
export default {
setup() {
const onOversize = (file) => {
console.log(file);
Toast('文件大小不能超過 500kb');
};
return {
onOversize,
};
},
};
如果需要針對(duì)不同類型的文件來作出不同的大小限制,可以在 max-size 屬性中傳入一個(gè)函數(shù),在函數(shù)中通過 file.type 區(qū)分文件類型,返回 true 表示超出限制,false 表示未超出限制。
<van-uploader multiple :max-size="isOverSize" />
import { Toast } from 'vant';
export default {
setup() {
const isOverSize = (file) => {
const maxSize = file.type === 'image/jpeg' ? 500 * 1024 : 1000 * 1024;
return file.size >= maxSize;
};
return {
isOverSize,
};
},
};
通過默認(rèn)插槽可以自定義上傳區(qū)域的樣式。
<van-uploader>
<van-button icon="plus" type="primary">上傳文件</van-button>
</van-uploader>
通過 preview-cover 插槽可以自定義覆蓋在預(yù)覽區(qū)域上方的內(nèi)容。
<van-uploader v-model="fileList">
<template #preview-cover="{ file }">
<div class="preview-cover van-ellipsis">{{ file.name }}</div>
</template>
</van-uploader>
<style>
.preview-cover {
position: absolute;
bottom: 0;
box-sizing: border-box;
width: 100%;
padding: 4px;
color: #fff;
font-size: 12px;
text-align: center;
background: rgba(0, 0, 0, 0.3);
}
</style>
通過傳入 beforeRead 函數(shù)可以在上傳前進(jìn)行校驗(yàn)和處理,返回 true 表示校驗(yàn)通過,返回 false 表示校驗(yàn)失敗。支持返回 Promise 對(duì) file 對(duì)象進(jìn)行自定義處理,例如壓縮圖片。
<van-uploader :before-read="beforeRead" />
import { Toast } from 'vant';
export default {
setup() {
// 返回布爾值
const beforeRead = (file) => {
if (file.type !== 'image/jpeg') {
Toast('請(qǐng)上傳 jpg 格式圖片');
return false;
}
return true;
};
// 返回 Promise
const asyncBeforeRead = (file) => {
return new Promise((resolve, reject) => {
if (file.type !== 'image/jpeg') {
Toast('請(qǐng)上傳 jpg 格式圖片');
reject();
} else {
const img = new File(['foo'], 'bar.jpg', {
type: 'image/jpeg',
});
resolve(img);
}
});
};
return {
beforeRead,
asyncBeforeRead,
};
},
};
通過 disabled 屬性禁用文件上傳。
<van-uploader disabled />
在 v-model 數(shù)組中設(shè)置單個(gè)預(yù)覽圖片屬性,支持 imageFit deletable previewSize beforeDelete。
<van-uploader v-model="fileList" :deletable="false" />
import { ref } from 'vue';
import { Toast } from 'vant';
export default {
setup() {
const fileList = ref([
{ url: 'https://img.yzcdn.cn/vant/leaf.jpg' },
{
url: 'https://img.yzcdn.cn/vant/sand.jpg',
deletable: true,
beforeDelete: () => {
Toast('自定義單個(gè)預(yù)覽圖片的事件和樣式');
},
},
{
url: 'https://img.yzcdn.cn/vant/tree.jpg',
deletable: true,
imageFit: 'contain',
previewSize: 120,
},
]);
return { fileList };
},
};
參數(shù) | 說明 | 類型 | 默認(rèn)值 |
---|---|---|---|
v-model | 已上傳的文件列表 | FileListItem[] | - |
accept | 允許上傳的文件類型,詳細(xì)說明 | string | image/*
|
name | 標(biāo)識(shí)符,可以在回調(diào)函數(shù)的第二項(xiàng)參數(shù)中獲取 | number | string | - |
preview-size | 預(yù)覽圖和上傳區(qū)域的尺寸,默認(rèn)單位為 px
|
number | string | 80px
|
preview-image | 是否在上傳完成后展示預(yù)覽圖 | boolean | true
|
preview-full-image | 是否在點(diǎn)擊預(yù)覽圖后展示全屏圖片預(yù)覽 | boolean | true
|
preview-options | 全屏圖片預(yù)覽的配置項(xiàng),可選值見 ImagePreview | object | - |
multiple | 是否開啟圖片多選,部分安卓機(jī)型不支持 | boolean | false
|
disabled | 是否禁用文件上傳 | boolean | false
|
readonly v3.1.5
|
是否將上傳區(qū)域設(shè)置為只讀狀態(tài) | boolean | false
|
deletable | 是否展示刪除按鈕 | boolean | true
|
show-upload | 是否展示上傳區(qū)域 | boolean | true
|
lazy-load | 是否開啟圖片懶加載,須配合 Lazyload 組件使用 | boolean | false
|
capture | 圖片選取模式,可選值為 camera (直接調(diào)起攝像頭) |
string | - |
after-read | 文件讀取完成后的回調(diào)函數(shù) | Function | - |
before-read | 文件讀取前的回調(diào)函數(shù),返回 false 可終止文件讀取,
支持返回 Promise
|
Function | - |
before-delete | 文件刪除前的回調(diào)函數(shù),返回 false 可終止文件讀取,
支持返回 Promise
|
Function | - |
max-size v3.0.17
|
文件大小限制,單位為 byte
|
number | string | (file: File) => boolean | - |
max-count | 文件上傳數(shù)量限制 | number | string | - |
result-type | 文件讀取結(jié)果類型,可選值為 file text
|
string | dataUrl
|
upload-text | 上傳區(qū)域文字提示 | string | - |
image-fit | 預(yù)覽圖裁剪模式,可選值見 Image 組件 | string | cover
|
upload-icon | 上傳區(qū)域圖標(biāo)名稱或圖片鏈接 | string | photograph
|
注意:accept、capture 和 multiple 為瀏覽器 input 標(biāo)簽的原生屬性,移動(dòng)端各種機(jī)型對(duì)這些屬性的支持程度有所差異,因此在不同機(jī)型和 WebView 下可能出現(xiàn)一些兼容性問題。
事件名 | 說明 | 回調(diào)參數(shù) |
---|---|---|
oversize | 文件大小超過限制時(shí)觸發(fā) | 同 after-read
|
click-upload v3.1.5
|
點(diǎn)擊上傳區(qū)域時(shí)觸發(fā) | event: MouseEvent |
click-preview | 點(diǎn)擊預(yù)覽圖時(shí)觸發(fā) | 同 after-read
|
close-preview | 關(guān)閉全屏圖片預(yù)覽時(shí)觸發(fā) | - |
delete | 刪除文件預(yù)覽時(shí)觸發(fā) | 同 after-read
|
名稱 | 說明 | 參數(shù) |
---|---|---|
default | 自定義上傳區(qū)域 | - |
preview-cover | 自定義覆蓋在預(yù)覽區(qū)域上方的內(nèi)容 | item: FileListItem |
before-read、after-read、before-delete 執(zhí)行時(shí)會(huì)傳遞以下回調(diào)參數(shù):
參數(shù)名 | 說明 | 類型 |
---|---|---|
file | file 對(duì)象 | object |
detail | 額外信息,包含 name 和 index 字段 | object |
result-type 字段表示文件讀取結(jié)果的類型,上傳大文件時(shí),建議使用 file 類型,避免卡頓。
值 | 描述 |
---|---|
file | 結(jié)果僅包含 File 對(duì)象 |
text | 結(jié)果包含 File 對(duì)象,以及文件的文本內(nèi)容 |
dataUrl | 結(jié)果包含 File 對(duì)象,以及文件對(duì)應(yīng)的 base64 編碼 |
通過 ref 可以獲取到 Uploader 實(shí)例并調(diào)用實(shí)例方法,詳見組件實(shí)例方法。
方法名 | 說明 | 參數(shù) | 返回值 |
---|---|---|---|
closeImagePreview | 關(guān)閉全屏的圖片預(yù)覽 | - | - |
chooseFile | 主動(dòng)調(diào)起文件選擇,由于瀏覽器安全限制,只有在用戶觸發(fā)操作的上下文中調(diào)用才有效 | - | - |
通過 UploaderInstance 獲取 Uploader 實(shí)例的類型定義。
import { ref } from 'vue';
import type { UploaderInstance } from 'vant';
const uploaderRef = ref<UploaderInstance>();
uploaderRef.value?.chooseFile();
組件提供了下列 CSS 變量,可用于自定義樣式,使用方法請(qǐng)參考 ConfigProvider 組件。
名稱 | 默認(rèn)值 | 描述 |
---|---|---|
--van-uploader-size | 80px | - |
--van-uploader-icon-size | 24px | - |
--van-uploader-icon-color | var(--van-gray-4) | - |
--van-uploader-text-color | var(--van-gray-6) | - |
--van-uploader-text-font-size | var(--van-font-size-sm) | - |
--van-uploader-upload-background-color | var(--van-gray-1) | - |
--van-uploader-upload-active-color | var(--van-active-color) | - |
--van-uploader-delete-color | var(--van-white) | - |
--van-uploader-delete-icon-size | 14px | - |
--van-uploader-delete-background-color | rgba(0, 0, 0, 0.7) | - |
--van-uploader-file-background-color | var(--van-background-color) | - |
--van-uploader-file-icon-size | 20px | - |
--van-uploader-file-icon-color | var(--van-gray-7) | - |
--van-uploader-file-name-padding | 0 var(--van-padding-base) | - |
--van-uploader-file-name-margin-top | var(--van-padding-xs) | - |
--van-uploader-file-name-font-size | var(--van-font-size-sm) | - |
--van-uploader-file-name-text-color | var(--van-gray-7) | - |
--van-uploader-mask-text-color | var(--van-white) | - |
--van-uploader-mask-background-color | fade(var(--van-gray-8), 88%) | - |
--van-uploader-mask-icon-size | 22px | - |
--van-uploader-mask-message-font-size | var(--van-font-size-sm) | - |
--van-uploader-mask-message-line-height | var(--van-line-height-xs) | - |
--van-uploader-loading-icon-size | 22px | - |
--van-uploader-loading-icon-color | var(--van-white) | - |
--van-uploader-disabled-opacity | var(--van-disabled-opacity) | - |
部分手機(jī)在拍照上傳時(shí)會(huì)出現(xiàn)圖片被旋轉(zhuǎn) 90 度的問題,這個(gè)問題可以通過 compressorjs 或其他開源庫進(jìn)行處理。
compressorjs 是一個(gè)開源的圖片處理庫,提供了圖片壓縮、圖片旋轉(zhuǎn)等能力。
使用 compressorjs 進(jìn)行處理的示例代碼如下:
<van-uploader :before-read="beforeRead" />
import Compressor from 'compressorjs';
export default {
setup() {
const beforeRead = (file) => {
return new Promise((resolve) => {
// compressorjs 默認(rèn)開啟 checkOrientation 選項(xiàng)
// 會(huì)將圖片修正為正確方向
new Compressor(file, {
success: resolve,
error(err) {
console.log(err.message);
},
});
});
};
return {
beforeRead,
};
},
};
目前 Chrome、Safari 等瀏覽器不支持展示 HEIC/HEIF 格式的圖片,因此上傳后無法在 Uploader 組件中進(jìn)行預(yù)覽。
[HEIF] 格式的兼容性請(qǐng)參考 caniuse。
更多建議: