关于vant组件库中uploader组件使用心得
vue3 vant组件库
技术栈:
Vue3+ts+vant
背景:
最近移动端项目中遇到了一个比较有意思的问题,需要根据不同的类别来上传对应的图片,并且将图片转换为url地址,在提交结果时,将地址也一并带上,最后一起上传。
具体需求的样图如下:
点击加减号添加项目名称,
选择完后弹框弹出对应名称,并且需要上传图片
个人遇到的问题:
上传图片本身不是什么难事,毕竟vant组件库已经是一个相对完善的组件库了,但是问题在于,如果未点击提交时关闭了弹框,此时又在加减号时添加了别的名称,再次弹框,按照原本组件库的逻辑就会出现图片无法对应名称的情况,并且点击x,想要删除图片时,就会报错
分析原因:
由于默认的uploader绑定的是一个数组,当我们改变了名称并再次弹框时,数组长度发生了变化,但是没有对应其名称,因此造成了错位的情况,在原数组中找不到对应名称的数组,在删除时就会出现问题
解决办法:
因为数组没办法做到图片和名称项对应,所以我们不考虑使用数组,改用对象的方式来存储图片
并且将上传和删除的回调函数写成如下模式
<Field
v-for="(item, index) in state.category.filter((target) => {
return target.submitResult > 0;
})"
:key="item.defectCategoryCode"
name="'uploader-' + index"
:label="item.defectProjectName"
>
<template #input>
<Uploader
multiple
:max-count="3"
capture="camera"
:key="'uploader-' + index"
preview-size="76"
v-model="fileList[item.code]" // 这个绑定对象,并用唯一的item.code做属性名
:before-read="beforeRead" // 上传前先压缩,这个可以自己写一下
:after-read="(file) => afterRead(file, item)" // 上传后转换为url
:before-delete="
(file, detail) => beforeDelete(file, item, item.code, detail) // 删除图片
"
/>
</template>
</Field>
上传时将原本绑定的数组改为对象,存储时以键值对的形式去存,属性名为唯一的code,值为对应的数组,在afterRead中,将每一项数据带入作为参数,并且将得到的url拼接到对应项的images中。
删除时将需要删除的fileList,每一项,每一项的code,以及index都传入,在fileList删除对应的上传图片,在item.images中删除对应url
const fileList = ref({}); // 图片数组
// 上传图片
const afterRead = async (file: any, item: any) => {
const formData = new FormData();
formData.append('file', file.file);
const res = await uploadImage(formData); // 图片上传
const regex = /^(.*?)(?=\?)/;
const url = res.data.match(regex)[1];
if (res.success) {
item.images = item.images
? (item.images += `,${url}`)
: (item.images = url);
}
};
// 删除图片
const beforeDelete = (file: any, item: any, name: any, detail: any) => {
const urlList = item.images.split(',');
urlList.splice(detail.index, 1);
(fileList.value as any)[name].splice(detail.index, 1);
item.images = urlList.join(',');
};
同时需要在弹框被关闭的colse方法中,将关闭时的图片信息都存进去,当再次打开弹框时,对比已经存储的信息和最新收集的信息是否相同,若相同则不做处理,不相同则替换掉,之后再打开弹框。
const closeHandle = () => {
modifyFlag.value = true;
temInfo.value = state.category;
};
const index = temInfo.value.findIndex(
(categoryItem: any) => categoryItem.code === item.code
);
if (index !== -1) {
temInfo.value[index].submitResult = item.submitResult;
} else {
temInfo.value.push(item);
}
});
state.category = modifyFlag.value ? temInfo.value : await getTargetInfo();
// getTargetInfo()为收集最新数据的函数
这样的话即使弹框被关闭或者修改选项,也能保证图片的上传和删除不受影响,并且不会报错,这个问题本身不算是什么大问题,就是对组件库的熟悉度不够导致的,在日后的开发中还需要深入对组件库的各种组件的理解和研究。
更多推荐
所有评论(0)