在使用v-md-editor的时候,发现上传图片时,url为base64在从尾部删除最后一个‘)’时会卡死,再说,base64所占篇幅确实不美观,于是我开始寻求解决办法
先展示:
这是v-md-editor编辑时:
这是提交的数据:
从第一张图片可以看到,url为(blob:http://),可惜v-md-editor的图片src并不支持这种url;
解决方法:
v-md-editor插件使用:
@save的方法我就不写了,与本文无关
<v-md-editor
:before-preview-change="previewChange"
ref="editor"
v-model="blogAddData.data.text"
:disabled-menus="[]"
height="1000px"
@upload-image="handleUploadImage"
@save="saveOrNext"/>
v-md-editor使用的响应式数据,相当于vue2里的data(){blogAddData:{xxx:xxx}}
const blogAddData = reactive({
editor: ref(),
data: {
// markdown展示的编辑区文章
text: '',
//最终提交的博客
article: '',
//博客中的图片url与base64
imgArray: [] as any[],
}
})
const {editor} = toRefs(blogAddData)
图片上传的方法,这里我没有上传图片,只是数据处理
//v-md-editor的上传图片方法@upload-image
const handleUploadImage = async (event: object, insertImage: Function, files: any[]) => {
//获取上传的文件
const file = files[0]
//获取文件名称
const fileName = file.name
//根据blob图片文件提取url,提取方法为blob2Url,下面会提到
const imageUrl = blob2Url(file)
//根据blob图片文件提取base64,提取方法为blob2Base64,下面会提到
const base64Img = await blob2Base64(file);
//写进img对象
const img = {
imageUrl,
base64Img
}
//将获取的url和base64编码放入响应式数组中
blogAddData.data.imgArray.push(img)
//v-md-editor的方法,用于展示图片
insertImage({
url: imageUrl,
desc: fileName
})
}
blob图片文件转url与base64的方法
/**
* blob转base64
* @param blob 文件
*/
const blob2Base64 = (blob: Blob) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.addEventListener('load', () => {
const base64 = reader.result?.toString() || '';
resolve(base64);
});
reader.addEventListener('error', () => {
reject(new Error('message'));
});
reader.readAsDataURL(blob);
});
}
/**
* blob转url
* @param blob 文件
*/
const blob2Url = (blob: Blob) => {
return URL.createObjectURL(blob);
}
v-md-editor提供了一个api来更改视图展示:before-preview-change,使用此参数来修改最终的展示:
const previewChange = (text: string, next: Function) => {
//使用正则表达式判断文章中是否有插入图片
if (text.search(checkBlobImg()) != -1) {
//如果有,则使用正则将生成的url全部筛选出来,并存入数组
const blobUrl = text.match(checkBlobUrl())
//这里使用的XEUtils工具类,arrayEach方法同foreach方法,没有装XEUtils插件,可使用foreach循环
//或者for循环,都一样
XEUtils.arrayEach(blobUrl!, (item: any) => {
//根据正则筛选出文中的url数组来筛选出blogAddData响应式中存储的url与base64数据
const arrayBlobUrl = blogAddData.data.imgArray.filter(value => value.imageUrl === item);
//将文中的url替换为base64
text = text.replace(item, arrayBlobUrl[0].base64Img)
//将处理好的文章赋给另一个变量,此变量就是最终提交的变量
//如果将text.replace(item, arrayBlobUrl[0].base64Img)直接赋值给blogAddData.data.articl
//会导致插入第二张图片时,第一张图片在编辑区展示base64代码
blogAddData.data.article = text;
})
} else {
没有插入图片时,直接赋值给blogAddData.data.article
blogAddData.data.article = text;
}
//让我们的操作生效
next(text)
}
//根据v-md-editor插入图片的格式编写的正则表达式来匹配,匹配规则为[!xxx](blob:http://xxxx)
const checkBlobImg = () =>{
return /!\[[^\]]*]\(blob:http:\/\/[^)]+\)/g;
}
//匹配url,规则为:blob:http://xxx以‘)’结束
const checkBlobUrl = () => {
return /blob:http:\/\/[^)]+/g
}
至此,此问题解决。