页面路由跳转 - 文件 File对象数据传递

目录

  • 需求
  • 主要问题点
    • 问题点2.1 演示
    • 问题点2.2 演示及解决
      • `页面B` 处理1 - 有问题
      • `页面B` 处理2 - 没有问题 - 最终解决办法
    • 【补充】 file 对象转为 base64 文件(即 将 file 对象转为 DataURL)

需求

页面A填写完信息(填写的信息中有上传的文件)之后需要跳转到页面B签名,然后在页面B内将填写的信息(包括上传的文件)和签名图片一起调用接口上传。

主要问题点

  1. 页面A 跳转到 页面B 需要携带页面A填写的信息(包括上传的文件 fileList 以及 其中File对象)
  2. 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

【注】
页面路由跳转 - 文件 File对象数据传递_第1张图片

问题点2.1 演示

页面A

// 路由跳转
this.$router.push({
  path: '/sign', // 跳转到签名的路由
  query: {
    // ...
    fileList: this.fileList, // 当前页面上传的文件需要在签名页面调接口和签名的图片一起上传
  }
})

页面B

 this.fileList = this.$route.query.fileList

页面 B 直接取 $route.query 中 fileList,file对象信息存在,没有问题
页面路由跳转 - 文件 File对象数据传递_第2张图片

刷新页面后出现问题:
页面路由跳转 - 文件 File对象数据传递_第3张图片

问题点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 对象丢失
页面路由跳转 - 文件 File对象数据传递_第4张图片

页面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 对象
页面路由跳转 - 文件 File对象数据传递_第5张图片

@/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)
  })
},

页面路由跳转 - 文件 File对象数据传递_第6张图片

你可能感兴趣的:(项目问题,JavaScript,文件问题,javascript,前端,开发语言)