目录
- 需求
- 主要问题点
- 问题点2.1 演示
- 问题点2.2 演示及解决
- `页面B` 处理1 - 有问题
- `页面B` 处理2 - 没有问题 - 最终解决办法
- 【补充】 file 对象转为 base64 文件(即 将 file 对象转为 DataURL)
需求
页面A填写完信息(填写的信息中有上传的文件)之后需要跳转到页面B签名,然后在页面B内将填写的信息(包括上传的文件)和签名图片一起调用接口上传。
主要问题点
- 页面A 跳转到 页面B 需要携带页面A填写的信息(包括上传的文件 fileList 以及 其中File对象)
this.$router.push()
通过 query 传参 fileList(两种方法主要是用不用JSON.parse()
处理的区别):
2.1 文件列表 fileList 直接携带:跳转到页面B可以取到其中的file
,【但是】页面刷新之后就没有了(详见下问题2.1演示)
2.2 文件列表 fileList 通过 JSON.parse() 转换携带:跳转到页面B JSON.stringify() 后fileList中的file
为空 (详见下问题2.2演示及解决)
【最终解决】问题点2.2 演示及解决:页面A
+页面B 处理2
【注】
问题点2.1 演示
页面A
// 路由跳转
this.$router.push({
path: '/sign', // 跳转到签名的路由
query: {
// ...
fileList: this.fileList, // 当前页面上传的文件需要在签名页面调接口和签名的图片一起上传
}
})
页面B
this.fileList = this.$route.query.fileList
页面 B 直接取 $route.query 中 fileList,file对象信息存在,没有问题
刷新页面后出现问题:
问题点2.2 演示及解决
页面A
this.fileList.forEach(async item => {
// console.log('item----', item)
// const base64 = await this.file2DataURL(item.file) // 此处不需要
// item.content = base64
item.filename = item.file.name // 接口上传文件时需要文件名,否则接口会报错
})
// 路由跳转
this.$router.push({
path: '/sign', // 跳转到签名的路由
query: {
// ...
fileList: JSON.stringify(this.fileList), // 当前页面上传的文件需要在签名页面调接口和签名的图片一起上传
}
})
页面B
处理1 - 有问题
this.fileList = JSON.parse(this.$route.query.fileList || '[]')
页面B
JSON.parse(this.$route.query.fileList || '[]')
处理后,file 对象丢失
页面B
处理2 - 没有问题 - 最终解决办法
import { dataURLtoFile } from '@/utils/index.js'
this.fileList = JSON.parse(this.$route.query.fileList || '[]')
this.fileList.forEach(item => {
const File = dataURLtoFile(item.content, item.filename, 'image/png') // 【主要代码 - 重点】将base64格式文件转为 file对象
item.file = File
})
页面B 中将页面A传过来的 base64 格式文件转为 file 对象
@/utils/index.js
/**
* 将 base64 转换为 file 对象
* dataURL:base64 格式
* fileName:文件名
* fileType:文件格式
*/
export function dataURLtoFile(dataURL, fileName, fileType) {
const arr = dataURL.split(',')
const mime = arr[0].match(/:(.*?);/)[1]
const bstr = atob(arr[1])
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], fileName, { type: fileType || 'image/jpg' })
}
【补充】 file 对象转为 base64 文件(即 将 file 对象转为 DataURL)
以上
问题点2.2 演示及解决 - 页面A
中我的 fileList 数据中有文件的 base64 格式,就可以直接传到页面B将该 base64 转为 file 对象。
如果自己的数据中没有 base64 格式的话,需要:将 页面A 中 file 对象转为 base64 格式 → 页面A将base64数据通过路由的 query 传到页面B → 页面B 接收到base64数据 → 再将 base64 转为 file 对象
file 对象转为 base64 文件
页面A
this.fileList.forEach(async item => {
// console.log('item----', item)
const base64 = await this.file2DataURL(item.file) // 【主要代码】
item.content = base64
item.filename = item.file.name // 接口上传文件时需要文件名,否则接口会报错
})
// 路由跳转
this.$router.push({
path: '/sign', // 跳转到签名的路由
query: {
// ...
fileList: JSON.stringify(this.fileList), // 当前页面上传的文件需要在签名页面调接口和签名的图片一起上传
}
})
// 【主要代码】file 对象转为 base64 文件(即 将 file 对象转为 DataURL)
file2DataURL(file) {
return new Promise(resolve => {
const reader = new FileReader()
reader.onload = () => {
resolve(reader.result)
}
reader.readAsDataURL(file)
})
},