vant的Uploader?文件上傳,圖片數(shù)據(jù)回顯問(wèn)題
vant的Uploader文件上傳,圖片數(shù)據(jù)回顯
需求


描述一下:點(diǎn)擊上傳證件照,選取需要的圖片文件,然后圖片在證件照欄展示
分析
看著挺簡(jiǎn)單的,用的是vant,里面有個(gè)文件上傳的組件Uploader,它里面的文件預(yù)覽模式是這樣的


啊這。。。
指定不行,還好它還有自定義上傳樣式的,像這樣

問(wèn)題又來(lái)了:選取文件后沒(méi)反應(yīng)了?。?!
其實(shí)也不是,沒(méi)有反應(yīng)就是沒(méi)有對(duì)文件數(shù)據(jù)進(jìn)行處理展示。
看一下Uploader的API:

參數(shù)file可以獲取到一個(gè)文件對(duì)象

可以拿到文件名、文件類(lèi)型、還有圖片的base64格式的圖片數(shù)據(jù),那么我們只需要定義一個(gè)字段來(lái)接受這個(gè)圖片數(shù)據(jù),并綁定給展示證件照的圖片框上就能實(shí)現(xiàn)圖片回顯了!
使用
結(jié)構(gòu)部分
<van-field name="photo" label="證件照" colon class="tx">
<template #input>
<van-image :src="staffPhoto ?staffPhoto : require('@/assets/icon/tx.png')" />
</template>
</van-field>
<van-uploader :before-read="beforeRead" :after-read="afterRead">
<van-button icon="add-o">上傳證件照</van-button>
</van-uploader>
方法部分
const afterRead = (file) => {
state.staffPhoto = file.content;
};
Uploader里面呢還有一個(gè)API:before-read

我們一般在這個(gè)里面對(duì)圖片的格式進(jìn)行控制
舉個(gè)栗子:
// 返回布爾值
const beforeRead = (file) => {
if (file.type !== "image/jpeg") {
Toast("請(qǐng)上傳 jpg 格式圖片");
return false;
}
return true;
};
當(dāng)然,我們也可以對(duì)圖片的大小進(jìn)行控制

自帶的事件oversize
const onOversize = () => {
Toast("文件大小不能超過(guò) 500kb");
};
結(jié)構(gòu)部分就是:
<van-uploader multiple :max-size="onOverSize" />
基本使用Uploader用到的功能就這些了,如果有其他的需求可以訪問(wèn)文檔:
使用有贊Vant上傳控件Uploader感悟
因?yàn)轫?xiàng)目是公眾號(hào)網(wǎng)頁(yè)項(xiàng)目,公司前端推薦使用有贊Vant組件庫(kù),這讓之前都是自己擼js,css的我仿佛打開(kāi)了新世界的大門(mén),廢話(huà)不多說(shuō),上正文。

照著官方文檔,我很快上手?jǐn)]出了界面。
<van-uploader v-model="fileList" multiple :max-count="4"/>
因?yàn)樾枨笳f(shuō)明最多只能上傳4張圖片,故使用了max-count來(lái)定義最大上傳數(shù)量。
數(shù)據(jù)處理
我上傳了一張照片,我們來(lái)看看fileList的數(shù)據(jù)是什么格式。

可以看到結(jié)果是一個(gè)數(shù)組array,每張圖片都轉(zhuǎn)為一個(gè)對(duì)象,對(duì)象下有兩個(gè)鍵值分別是:content->圖片base64編碼(有贊這個(gè)Uploader很貼心的幫我們把圖片轉(zhuǎn)成base64格式流),file->一個(gè)文件對(duì)象,包含了文件名,上傳路徑,文件類(lèi)型,文件大小等。
看完了數(shù)據(jù),后端需要我們把文件傳給他們,這里有一點(diǎn)需要注意,base64編碼由于長(zhǎng)度原因,請(qǐng)求方式必須用POST。
let photos = []
that.fileList.forEach(v=> {
let o = {
base64Str: v.content,
filename: v.file.name
}
photos.push(o)
})通過(guò)axios請(qǐng)求后臺(tái)
axios.request({
url: '/x/xxx/api',
data: {
photos: photos
},
method: 'POST'
})后臺(tái)處理
@RequestMapping(value = "/api", method = RequestMethod.POST)
public JSONObject xxx(@RequestBody JSONObject jsonObject) {
JSONArray photos = jsonObject.getJSONArray("photos");
if (photos.size() > 0) {
for (int i = 0; i < photos.size(); i++) {
JSONObject obj = photos.getJSONObject(i);
String fileName = obj.getString("filename");
String base64Str = obj.getString("base64Str");
String directoryName = "xx/xx";
String extension = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
InputStream inputStream = new ByteArrayInputStream(Base64.decodeBase64(base64Str.substring(base64Str.indexOf(",") + 1)));
OSSClient client = new OSSClient(endpoint, accessKeyId, accessKeySecret);
client.putObject(bucketName, getRandomKey(directoryName, extension), inputStream); // extension指的是拓展名,例如".amr"
}
}
}
/**
* 隨機(jī)生成一個(gè)key
* @return String 隨機(jī)key
*/
public static String getRandomKey(String directoryName, String extension){
StringBuffer key = new StringBuffer();
if (StringUtils.isNotBlank(directoryName)) {
key.append(directoryName);
if (directoryName.charAt(directoryName.length() - 1) != '/') {
key.append("/");
}
}
key.append(System.currentTimeMillis());
for (int i = 0; i < 10; i++) {
key.append(randomStr.charAt(RandomUtils.nextInt(0, randomStr.length())));
}
if (StringUtils.isNotBlank(extension)) {
if (extension.indexOf(".") == -1) {
key.append(".");
}
key.append(extension);
}
return key.toString();
}后臺(tái)處理需要注意下base64編碼,我先把base64Str解碼轉(zhuǎn)為byte[]數(shù)組,因?yàn)轫?xiàng)目使用阿里的OSSClient,上傳過(guò)程還是比較簡(jiǎn)單。
整個(gè)流程做完了,感覺(jué)組件大大縮減了開(kāi)發(fā)和調(diào)試時(shí)間。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- vant的Loading加載動(dòng)畫(huà)組件的使用(通過(guò)接口拿數(shù)據(jù)時(shí)顯示加載狀態(tài))
- vant-list組件觸發(fā)多次onload事件導(dǎo)致數(shù)據(jù)亂序的解決方案
- Vue3+vant+ts 上滑加載解決上滑調(diào)用多次數(shù)據(jù)的問(wèn)題(推薦)
- 使用Vant如何實(shí)現(xiàn)數(shù)據(jù)分頁(yè),下拉加載
- vant遇到van-sidebar數(shù)據(jù)超出不能滑動(dòng)的問(wèn)題
- vant中的Cascader級(jí)聯(lián)選擇異步加載地區(qū)數(shù)據(jù)方式
相關(guān)文章
vue使用vue-video-player插件播放視頻的步驟講解
在最近的項(xiàng)目中有一個(gè)視頻播放的功能,在之前的項(xiàng)目中沒(méi)有接觸過(guò)類(lèi)似的功能,第一次接觸,把具體操作步驟一下,這篇文章主要給大家介紹了關(guān)于vue使用vue-video-player插件播放視頻的相關(guān)資料,需要的朋友可以參考下2022-12-12
vue element-ui里的table中表頭與表格出現(xiàn)錯(cuò)位的解決
這篇文章主要介紹了vue element-ui里的table中表頭與表格出現(xiàn)錯(cuò)位的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
vue中element 的upload組件發(fā)送請(qǐng)求給后端操作
這篇文章主要介紹了vue中element 的upload組件發(fā)送請(qǐng)求給后端操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09
vue element-ui實(shí)現(xiàn)動(dòng)態(tài)面包屑導(dǎo)航
這篇文章主要為大家詳細(xì)介紹了vue element-ui實(shí)現(xiàn)動(dòng)態(tài)面包屑導(dǎo)航,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12
Vue使用mind-map實(shí)現(xiàn)在線(xiàn)思維導(dǎo)圖
Vue中的Mind-Map通常是指使用Vue.js這個(gè)前端框架構(gòu)建的思維導(dǎo)圖組件或庫(kù),它可以幫助開(kāi)發(fā)者在Web應(yīng)用中創(chuàng)建動(dòng)態(tài)、交互式的思維導(dǎo)圖,讓用戶(hù)可以直觀地組織信息和結(jié)構(gòu)化數(shù)據(jù),本文介紹了Vue使用mind-map實(shí)現(xiàn)在線(xiàn)思維導(dǎo)圖,需要的朋友可以參考下2024-07-07
Vue?編程式路由導(dǎo)航的實(shí)現(xiàn)示例
本文主要介紹了Vue?編程式路由導(dǎo)航2022-04-04
vue多級(jí)復(fù)雜列表展開(kāi)/折疊及全選/分組全選實(shí)現(xiàn)
這篇文章主要介紹了vue多級(jí)復(fù)雜列表展開(kāi)/折疊及全選/分組全選實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-11-11

