VUE中使用el-upload不立即上传图片,待点击提交后才上传到本地文件夹

一、效果图及其描述

使用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>

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
1. 安装element-ui和axios ``` npm install element-ui axios ``` 2. 在main.js引入element-ui和axios ```javascript import Vue from 'vue' import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' import axios from 'axios' Vue.use(ElementUI) Vue.prototype.$axios = axios ``` 3. 在组件使用el-upload组件 ```html <template> <div> <el-upload class="upload-demo" action="/api/upload" :on-success="handleSuccess" :before-upload="beforeUpload" :headers="{Authorization: token}"> <el-button size="small" type="primary">点</el-button> <div slot="tip" class="el-upload__tip">只能上jpg/png文件,且不超过500kb</div> </el-upload> </div> </template> ``` 其,action是上的接口地址,on-success是上成功后的回调函数,before-upload是上前的钩子函数,headers是请求头部,可以递token等信息。 4. 在methods定义handleSuccess和beforeUpload函数 ```javascript methods: { handleSuccess(response, file, fileList) { console.log(response) // 在这里处理上成功后的响应数据 }, beforeUpload(file) { const isJPG = file.type === 'image/jpeg' || file.type === 'image/png' const isLt500K = file.size / 1024 < 500 if (!isJPG) { this.$message.error('上图片只能是 JPG/PNG 格式!') } if (!isLt500K) { this.$message.error('上图片大小不能超过 500KB!') } return isJPG && isLt500K } } ``` 在beforeUpload函数,可以对上图片进行格式、大小等限制。 5. 在后端接口处理上图片 在后端接口,可以使用express框架的multer间件来处理上图片。安装multer: ``` npm install multer ``` 在express引入multer,并设置上文件夹: ```javascript const express = require('express') const multer = require('multer') const app = express() const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, 'uploads/') }, filename: function (req, file, cb) { cb(null, file.fieldname + '-' + Date.now() + '.jpg') } }) const upload = multer({ storage: storage }) app.post('/api/upload', upload.single('file'), (req, res) => { console.log(req.file) // 在这里处理上成功后的响应数据 }) ``` 在这里,上的文件会被保存到uploads文件夹下,文件名会以字段名和时间戳命名。 注意:在使用express间件处理上文件时,需要使用body-parser间件。安装body-parser: ``` npm install body-parser ``` 在express引入body-parser: ```javascript const bodyParser = require('body-parser') app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.json()) ``` 完整代码如下: ```javascript const express = require('express') const multer = require('multer') const bodyParser = require('body-parser') const app = express() const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, 'uploads/') }, filename: function (req, file, cb) { cb(null, file.fieldname + '-' + Date.now() + '.jpg') } }) const upload = multer({ storage: storage }) app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.json()) app.post('/api/upload', upload.single('file'), (req, res) => { console.log(req.file) // 在这里处理上成功后的响应数据 }) app.listen(3000, () => console.log('Server is running...')) ``` 注意:在使用element-ui的上组件时,需要设置上的文件类型和大小限制,但是这只是客户端的限制,如果后端没有做相应的处理,仍然可以上非指定类型和大小的文件,因此,在后端接口也需要对上的文件进行相应的限制。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值