background

The project uses VUE-CLI + Vant, which has a picture uploading function. The Uploader component of Vant was used at the beginning

The component is easy to use, both upload, and encapsulated image preview function

But there is a problem, is part of the Android limit undead single upload, batch upload support is not good, fortunately, batch upload special processing can also be done

First add the attribute multiple=”true” to the component, and then process the after-read callback, which determines whether the uploaded file is an array

// Handle the after-read function
handleAfterRead(file, detail){
  // Check whether the file argument is an array
  if(Array.isArray(file)){
    // loop to call interface upload
  }else {
    // Call interface upload}}Copy the code

Limit the type, number, and size of immortal files, so check again in after-read callback

// Handle the after-read function
handleAfterRead(file, detail){
  // Check whether the file argument is an array
  if(Array.isArray(file)){
    // You can upload only 9 photos at a time
    if (file.length > 9) {
      console.log('Upload up to 9 at a time, please upload in batches! ')
      return
    }

    // loop to call interface upload
  }else {
    // Restrict uploads to image-type files
    if(! file.file.type.includes('image')) {console.log('Upload failed, can only upload photos! ')
      return
    }
    // The size of uploaded images cannot exceed 10M
    if(! file.file.size >=1024 * 1024 * 10) {console.log('The file is too large and cannot exceed 10M! ')
      return
    }

    // Call interface upload}}Copy the code

The limit was fine, but then another problem arose, that is, although the size of a single image uploaded cannot exceed 10M, the size of pictures uploaded through photography is generally 3-5m

Therefore, the upload speed is very slow, and it is easy to upload timeout, resulting in the interface error upload failure

It was decided to compress the image before calling the interface to upload, using the CompressorJS plugin recommended by Vant

npm i compressorjs -S
Copy the code
// Handle the after-read function
async handleAfterRead(file, detail){
  // Check whether the file argument is an array
  if(Array.isArray(file)){
    // restrict judgment
    
    // loop the compression process and call the interface upload

    // loop to call interface upload
  }else {
    // restrict judgment
    
    // compress
    const img = await compressor(file.file,0.2)

    // Call interface upload}}// Compression method
// Start with compressorjs
import Compressor from 'compressorjs'
/** * @file file * @quality Image compression quality */
function compressor(file,quality) {
  return new Promise(resolve= > {
    new Compressor(file, {
      quality,
      success: resolve,
      error(err) {
        console.log(err.message)
      },
    })
  })
}
Copy the code

At this point, the picture upload is not too big a problem, in the front end is almost optimized to the extreme, the rest is the problem of the interface, such as interface instability, interface processing slow problems…

Finally, a front-end direct upload to Ali Cloud OSS method is introduced

Install the OSS NPM package first

npm i ali-oss -S
Copy the code

Encapsulating OSS (SRC /utils/oss.js)

const OSS = require('ali-oss')
const OSSConfig = {
  uploadHost: 'https://XXXXXX.oss-cn-shenzhen.aliyuncs.com'.folder: 'test/'.region: 'oss-cn-shenzhen'.accessKeyId: 'XXXXXXXXXXXXXXXXX'.accessKeySecret: 'XXXXXXXXXXXXXXXXXXXXXXXX'.bucket: 'XXXXX',}function uploadOSS(file){
  return new Promise(async (resolve, reject) => {
    const fileName = `${OSSConfig.folder}${file.name}`
    const client = new OSS({
      region: OSSConfig.region,
      accessKeyId: OSSConfig.accessKeyId,
      accessKeySecret: OSSConfig.accessKeySecret,
      bucket: OSSConfig.bucket,
    })
    const res = await client.multipartUpload(fileName, file)
    if (res.name) {
      resolve({
        // Upload file name
        fileName: file.name,
        url: `${OSSConfig.uploadHost}/${fileName}`})}else {
      reject('OSS upload failed ')}}}export { uploadOSS }
Copy the code

use

import { uploadOSS } from '@/utils/oss'

const { fileName, url } = await uploadOSS(file)
Copy the code