vant的Uploader文件上传,图片数据回显

需求

vant的Uploader 文件上传,图片数据回显问题
vant的Uploader 文件上传,图片数据回显问题

描述一下:点击上传证件照,选取需要的图片文件,然后图片在证件照栏展示

分析

看着挺简单的,用的是vant,里面有个文件上传的组件Uploader,它里面的文件预览模式是这样的

vant的Uploader 文件上传,图片数据回显问题vant的Uploader 文件上传,图片数据回显问题

啊这。。。

指定不行,还好它还有自定义上传样式的,像这样

vant的Uploader 文件上传,图片数据回显问题

问题又来了:选取文件后没反应了!!!

其实也不是,没有反应就是没有对文件数据进行处理展示。

看一下Uploader的API:

vant的Uploader 文件上传,图片数据回显问题

参数file可以获取到一个文件对象

vant的Uploader 文件上传,图片数据回显问题

可以拿到文件名、文件类型、还有图片的base64格式的图片数据,那么我们只需要定义一个字段来接受这个图片数据,并绑定给展示证件照的图片框上就能实现图片回显了!

使用

结构部分

      <van-field name="photo" label="证件照" colon class="tx">
<template #input>
<van-image :src="')" />
</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里面呢还有一个API:before-read

vant的Uploader 文件上传,图片数据回显问题

我们一般在这个里面对图片的格式进行控制

举个栗子:

    // 返回布尔值
const beforeRead = (file) => {
if (file.type !== "image/jpeg") {
Toast("请上传 jpg 格式图片");
return false;
}
return true;
};

当然,我们也可以对图片的大小进行控制

vant的Uploader 文件上传,图片数据回显问题

自带的事件oversize

	const onOversize = () => {
Toast("文件大小不能超过 500kb");
};

结构部分就是:

<van-uploader multiple :max-size="onOverSize" />

基本使用Uploader用到的功能就这些了,如果有其他的需求可以访问文档:

Uploader的基本使用

使用有赞Vant上传控件Uploader感悟

因为项目是公众号网页项目,公司前端推荐使用有赞Vant组件库,这让之前都是自己撸js,css的我仿佛打开了新世界的大门,废话不多说,上正文。

vant的Uploader 文件上传,图片数据回显问题

照着官方文档,我很快上手撸出了界面。

<van-uploader v-model="fileList" multiple :max-count="4"/>

因为需求说明最多只能上传4张图片,故使用了max-count来定义最大上传数量。

数据处理

我上传了一张照片,我们来看看fileList的数据是什么格式。

vant的Uploader 文件上传,图片数据回显问题

可以看到结果是一个数组array,每张图片都转为一个对象,对象下有两个键值分别是:content->图片base64编码(有赞这个Uploader很贴心的帮我们把图片转成base64格式流),file->一个文件对象,包含了文件名,上传路径,文件类型,文件大小等。

看完了数据,后端需要我们把文件传给他们,这里有一点需要注意,base64编码由于长度原因,请求方式必须用POST。

let photos = []
that.fileList.forEach(v=> {
let o = {
base64Str: v.content,
filename: v.file.name
}
photos.push(o)
})

通过axios请求后台

axios.request({
url: '/x/xxx/api',
data: {
photos: photos
},
method: 'POST'
})

后台处理

@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"
}
}
}
/**
* 随机生成一个key
* @return String 随机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();
}

后台处理需要注意下base64编码,我先把base64Str解码转为byte[]数组,因为项目使用阿里的OSSClient,上传过程还是比较简单。

整个流程做完了,感觉组件大大缩减了开发和调试时间。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持本站。

发表回复