vant的图片上传组件预览问题

先记录问题:主要是我直接吧图片的base64字符串存入了数据库,再次打开页面加载图片时,要么就是页面显示图片错误,要么就是点击图片预览时查看失败(因为使用的vue+vant+cordova+sqlite实现单机版应用,不希望联网,所以直接把图片存数据库了)。vant版本是4.8.0

<van-cell-group >
				<van-field label="图片" >
	    			<template #input>
					    <van-uploader v-model="fileList" :after-read="afterRead"  />
				  	</template>
	    		</van-field>
			</van-cell-group>

当file对象设置属性url值是"data:image/png;base64,iVBORw0KG..."格式时,页面显示如下:

for(var i=0;i<data.length;i++){
			fileList.value.push({url: data[i].content});
			//fileList.value.push({content: data[i].content, objectUrl: createObjectURL(data[i].content)});
}

当file对象设置属性content值是"data:image/png;base64,iVBORw0KG..."格式时,页面可以正常显示,但是一点击图片预览,可以正常放大预览的,可是页面显示却不正常了,变为上面样子了。

for(var i=0;i<data.length;i++){
			//fileList.value.push({url: data[i].content});
			fileList.value.push({content: data[i].content, objectUrl: createObjectURL(data[i].content)});
		}

const createObjectURL = function(base64Data){
	// Base64编码的图片数据
	//var base64Data = "data:image/png;base64,iVBORw0KG..."; // 这里只展示部分内容
	 
	// 获取Base64编码的图片类型(如PNG、JPEG等)
	var imageType = base64Data.split(',')[0].match(/:(.*?);/)[1];
	 
	// 去除Base64编码头信息并进行URL解码
	var dataUrl = window.atob(base64Data.split(",")[1]);
	 
	// 创建Uint8Array类型的字节数组
	var byteCharacters = new Uint8Array(dataUrl.length);
	for (let i = 0; i < dataUrl.length; i++) {
		byteCharacters[i] = dataUrl.charCodeAt(i);
	}
	 
	// 创建Blob对象
	var blob = new Blob([byteCharacters], { type: imageType });
	//通过URL.createObjectURL(blob)可以获取当前文件的一个内存URL
	var url = URL.createObjectURL(blob);
	return url;
}

点击图片预览前,页面显示正常。

点击图片预览后,页面显示异常:

如果不设置objectUrl属性,则点击图片无法正常预览。

试了很多方法都没办法达到预期效果。于是决定修改vant的源码。

vant的图片上传组件文件路径vant/es/uploader/Uploader.mjs(或者vant/lib/uploader/Uploader.js),原来的代码如下:

    const previewImage = (item) => {
      if (props.previewFullImage) {
        const imageFiles = props.modelValue.filter(import_utils2.isImageFile);
        const images = imageFiles.map((item2) => {
          if (item2.objectUrl && !item2.url && item2.status !== "failed") {
            item2.url = item2.objectUrl;
            urls.push(item2.url);
          }
          return item2.url;
        }).filter(Boolean);
        imagePreview = (0, import_image_preview.showImagePreview)((0, import_utils.extend)({
          images,
          startPosition: imageFiles.indexOf(item),
          onClose: onClosePreview
        }, props.previewOptions));
      }
    };

问题估计就是在里面那个if语句上面。修改后的源码:

    const previewImage = (item) => {
      if (props.previewFullImage) {
        const imageFiles = props.modelValue.filter(isImageFile);
        const images = imageFiles.map((item2) => {
          if (item2.objectUrl && !item2.url && item2.status !== "failed") {
			if(item2.objectUrl.indexOf("blob:") == 0){
				return item2.objectUrl;
			}
            item2.url = item2.objectUrl;
            urls.push(item2.url);
          }
          return item2.url;
        }).filter(Boolean);
        imagePreview = showImagePreview(extend({
          images,
          startPosition: imageFiles.indexOf(item),
          onClose: onClosePreview
        }, props.previewOptions));
      }
    };

然后清空缓存,重新启动调试,测试正常。

注意修改node_modules下面的源码后,需要删除vite的缓存。即deps目录(建议删除前先备份)。然后npm run dev重新启动。

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值