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