一、效果图及其描述

使用auto-upload属性,令图片不立即上传,但确能显示在前端一个缓存预览的效果,待页面刷新后,缓存预览的图片消失。只有点击了“提交”按钮后,图片才会保存到本地文件夹中,不会消失。

二、方法

第一步,先配置接口文件server/router.js,接口为post请求,请求为"localhost:8888/upload"

const fs = require('fs')
const multer = require('multer')
const express = require('express')
const router = express.Router()
 
/** 导入图片
 * POST
 * /upload
 * */
var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, './upload')
  },
  filename: function (req, file, cb) {
    // 设置保存文件的名称,这里以时间代替原文件名[file.originalname]
    cb(null, Date.now() + '.jpg')
  }
})
 
var createFolder = function (folder) {
  try {
    fs.accessSync(folder)
  } catch (e) {
    fs.mkdirSync(folder)
  }
}
 
var uploadFolder = './upload/'
createFolder(uploadFolder)
var upload = multer({
  storage: storage
})
 
router.post('/upload', upload.single('file'),
  function (req, res, next) {
    var file = req.file
    console.log(file)
    res.send(file)
  })
 
module.exports = router

第二步,搭建服务端口文件server/index.js,用于引用接口文件和使用端口localhost:8888

// 搭建express服务
const express = require('express')
const app = express()

// post请求表单数据
app.use(express.urlencoded({extended: true}))

// 静态文件托管,通过localhost:8888/readupload/文件名.jpg可查看文件
app.use('/readupload', express.static('upload'))

// 路由
const router = require('./router')

app.use('/', router)

app.listen(8888, () => {
  console.log(8888)
})

第三步,配置vue页面,因为auto-upload属性为false时,on-success和before-upload属性会失效,我们将他们的操作移到on-change中来(上传变化的钩子)。

<template>
  <div>
    <el-upload
      class="avatar-uploader"
      :action="url"
      :auto-upload="false"
      :show-file-list="false"
      :on-change="upldchange">
      <img v-if="imageUrl" :src="imageUrl" class="avatar">
      <i v-else class="el-icon-plus avatar-uploader-icon"></i>
    </el-upload>
    <el-button type="primary" @click="submitupload()">提交</el-button>
    <!--显示保存到本地的图片-->
    <img v-if="baseurl !== ''" :src="require('../../server/upload/' + baseurl)" style="width: 100px;height: 100px;">
  </div>
</template>
<script>
export default {
  data () {
    return {
      baseurl: '',
      imageUrl: '', // 预览图片地址
      files: [], // 复刻文件数据
      url: '' // 因为auto-upload元素,action设置为空
    }
  },
  methods: {
    // 上传框状态改变监听事件
    upldchange (file) {
      // 文件格式大小判断处理
      const isJPG = file.raw.type === 'image/jpeg'
      const isLt2M = file.raw.size / 1024 / 1024 < 2

      if (!isJPG) {
        this.$message.error('上传头像图片只能是 JPG 格式!')
        return
      }
      if (!isLt2M) {
        this.$message.error('上传头像图片大小不能超过 2MB!')
        return
      }

      // 格式无误后,预览文件处理
      this.imgSaveToUrl(file)
      // 复刻文件信息
      this.files = file.raw
      console.log(this.files)
    },
    // 提交按钮监听事件
    submitupload () {
      // 判断是否存在预览图片信息,才执行post请求
      if (this.files.length !== 0) {
        // 赋值给formData
        let formData = new FormData()
        formData.append('file', this.files)
        // POST接口请求
        this.$axios.post('/api/upload', formData)
          .then((res) => {
            console.log('成功')
            console.log(res)
            this.baseurl = res.data.filename
          })
          .catch((error) => {
            console.log('失败')
            console.log(error)
          })
      } else {
        // 没有预览图片文件处理
        this.$message({
          message: '请选择图片!',
          type: 'error',
          duration: 1500
        })
      }
    },
    // 获取选中图片的预览路径,并赋值给本地img路径,在前端展示
    imgSaveToUrl (file) {
      // 获取上传图片的本地URL,用于上传前的本地预览,转换后的地址为 blob:http://xxx/7bf54338-74bb-47b9-9a7f-7a7093c716b5
      this.imageUrl = URL.createObjectURL(file.raw)
      console.log('图片预览地址:', this.imageUrl)
    }
  }
}
</script>

Logo

前往低代码交流专区

更多推荐