您的位置 首页 golang

vue-element-admin 上传upload图片慢问题处理


前言

vue-element-admin自带上传图片组件,在使用的过程中发现上传速度很慢,尤其是上传一些大图需要耗时几十秒不能忍受。出现这种情况,是因为upload组件会将图片上传到action="https://httpbin.org/post" ,并返回转换成base64编码格式的数据。

格式类似:

data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAIBAQEBAQIBAQECAgICAgQDAgICAgUEBAMEBgUGBgYFBgYGBwkIBgcJBwYGCAsIC.....

而且有可能这个base64编码比上传源文件还要大。

这样做有两个缺点:

  • 多一步上传文件到第三方网站(https://httpbin.org/post),并转码base64,其中大部分时间在这一步浪费的。
  • 服务端在接收base64编码内容,还要将其处理成文件进行单独保存(base64编码内容太长,通常不会直接存入数据库),这给服务端带来不便。

还有一点就这种是必须图片和表单其他内容一起提交,有的时候上传和表单其他项分开提交。

接下来讲一下如何将图片单独上传到服务的实现步骤:

具体代码在以下项目里

github:

https://github.com/guyan0319/…

码云(国内):

https://gitee.com/jason0319/g…

示例一、解决如下图所示的上传和删除

vue-element-admin 上传upload图片慢问题处理

1、新建文件

vue-element-adminsrcutilsglobal.js

内容如下

const httphost = 'http://localhost:8090'export { httphost }

这个是服务端的地址,可以根据需要自己调整。

2、修改上传组件代码在SingleImage3.vue

上传图片

引入上面定义的服务器地址

import { httphost } from '@/utils/global'

data()增加uploadUrl

data() {    return {      tempUrl: '',      uploadUrl: httphost + '/upload/image',      dataObj: { token: '', key: '' }    }  },

action=``"https://httpbin.org/post" 

修改为

 :action="uploadUrl"

图片上传成功on-success绑定的handleImageSuccess函数增加了res,即服务端返回上传结果。

修改代码如下

handleImageSuccess(res, file) {      if (res.code !== 20000){        this.$message({          message: '上传失败',          type: 'error',          showClose: true        })        return false      }      this.emitInput(res.data)    },

服务端返回的json格式为

{    "code":20000,    "data":"http://localhost:8090/showimage?imgname=upload/20200620/tX5vS810l2Fl0K02I0YJLEjLEw9OH7hc.jpg"}

这里需要注意el-upload增加

:with-credentials='true'

支持发送 cookie 凭证信息,上传文件到服务器端需要判断验证登录。

删除图片

通过以上修改实现上传图片,接下处理上传文件删除

文件api/article.js 增加

export function delImage(url) {  return request({    url: '',    method: 'get',    params: { url },    baseURL: httphost + '/del/image'  })}

修改SingleImage3.vue

//引入delImageimport { delImage } from '@/api/article'
  rmImage() {      delImage(this.value).then(response => {        if (response.code === 20000){          this.emitInput('')          return        }        this.$message({          message: '删除失败',          type: 'error',          showClose: true        })      }).catch(err => {        console.log(err)      })    },

服务端删除文件返回json

{"code":20000,"data":"success"}

最后贴一下SingleImage3.vue修改后完整的代码

<template>  <div class="upload-container">    <el-upload      :data="dataObj"      :multiple="false"      :show-file-list="false"      :with-credentials='true'      :on-success="handleImageSuccess"      class="image-uploader"      drag      :action="uploadUrl"    >      <i class="el-icon-upload" />      <div class="el-upload__text">        将文件拖到此处,或<em>点击上传</em>      </div>    </el-upload>    <div class="image-preview image-app-preview">      <div v-show="imageUrl.length>1" class="image-preview-wrapper">        <img :src="imageUrl">        <div class="image-preview-action">          <i class="el-icon-delete" @click="rmImage" />        </div>      </div>    </div>    <div class="image-preview">      <div v-show="imageUrl.length>1" class="image-preview-wrapper">        <img :src="imageUrl">        <div class="image-preview-action">          <i class="el-icon-delete" @click="rmImage" />        </div>      </div>    </div>  </div></template><script>import { getToken } from '@/api/qiniu'import { delImage } from '@/api/article'import { httphost } from '@/utils/global'// import { Cookies } from 'js-cookie'export default {  name: 'SingleImageUpload3',  props: {    value: {      type: String,      default: ''    }  },  data() {    return {      tempUrl: '',      uploadUrl: httphost + '/upload/image',      dataObj: { token: '', key: '' }    }  },  computed: {    imageUrl() {      return this.value    }  },  methods: {    rmImage() {      delImage(this.value).then(response => {        if (response.code === 20000){          this.emitInput('')          return        }        this.$message({          message: '删除失败',          type: 'error',          showClose: true        })      }).catch(err => {        console.log(err)      })    },    emitInput(val) {      this.$emit('input', val)    },    handleImageSuccess(res, file) {      if (res.code !== 20000){        this.$message({          message: '上传失败',          type: 'error',          showClose: true        })        return false      }      this.emitInput(res.data)    },    beforeUpload() {      const _self = this      return new Promise((resolve, reject) => {        getToken().then(response => {          const key = response.data.qiniu_key          const token = response.data.qiniu_token          _self._data.dataObj.token = token          _self._data.dataObj.key = key          this.tempUrl = response.data.qiniu_url          resolve(true)        }).catch(err => {          console.log(err)          reject(false)        })      })    }  }}</script><style lang="scss" scoped>@import "~@/styles/mixin.scss";.upload-container {  width: 100%;  position: relative;  @include clearfix;  .image-uploader {    width: 35%;    float: left;  }  .image-preview {    width: 200px;    height: 200px;    position: relative;    border: 1px dashed #d9d9d9;    float: left;    margin-left: 50px;    .image-preview-wrapper {      position: relative;      width: 100%;      height: 100%;      img {        width: 100%;        height: 100%;      }    }    .image-preview-action {      position: absolute;      width: 100%;      height: 100%;      left: 0;      top: 0;      cursor: default;      text-align: center;      color: #fff;      opacity: 0;      font-size: 20px;      background-color: rgba(0, 0, 0, .5);      transition: opacity .3s;      cursor: pointer;      text-align: center;      line-height: 200px;      .el-icon-delete {        font-size: 36px;      }    }    &:hover {      .image-preview-action {        opacity: 1;      }    }  }  .image-app-preview {    width: 320px;    height: 180px;    position: relative;    border: 1px dashed #d9d9d9;    float: left;    margin-left: 50px;    .app-fake-conver {      height: 44px;      position: absolute;      width: 100%; // background: rgba(0, 0, 0, .1);      text-align: center;      line-height: 64px;      color: #fff;    }  }}</style>

示例二、解决如下图所示的上传

vue-element-admin 上传upload图片慢问题处理

需要修改vue-element-adminsrccomponentsTinymcecomponentsEditorImage.vue文件,处理方式和示例一差不多,这里只贴代码

<template>  <div class="upload-container">    <el-button :style="{background:color,borderColor:color}" icon="el-icon-upload" size="mini" type="primary" @click=" dialogVisible=true">      upload    </el-button>    <el-dialog :visible.sync="dialogVisible">      <el-upload        :multiple="true"        :file-list="fileList"        :show-file-list="true"        :with-credentials='true'        :on-remove="handleRemove"        :on-success="handleSuccess"        :before-upload="beforeUpload"        class="editor-slide-upload"        :action="uploadUrl"        list-type="picture-card"      >        <el-button size="small" type="primary">          Click upload        </el-button>      </el-upload>      <el-button @click="dialogVisible = false">        Cancel      </el-button>      <el-button type="primary" @click="handleSubmit">        Confirm      </el-button>    </el-dialog>  </div></template><script>// import { getToken } from 'api/qiniu'import { delImage } from '@/api/article'import { httphost } from '@/utils/global'export default {  name: 'EditorSlideUpload',  props: {    color: {      type: String,      default: '#1890ff'    }  },  data() {    return {      dialogVisible: false,      uploadUrl: httphost + '/upload/image',      listObj: {},      fileList: []    }  },  methods: {    checkAllSuccess() {      return Object.keys(this.listObj).every(item => this.listObj[item].hasSuccess)    },    handleSubmit() {      const arr = Object.keys(this.listObj).map(v => this.listObj[v])      if (!this.checkAllSuccess()) {        this.$message('Please wait for all images to be uploaded successfully. If there is a network problem, please refresh the page and upload again!')        return      }      this.$emit('successCBK', arr)      this.listObj = {}      this.fileList = []      this.dialogVisible = false    },    handleSuccess(response, file) {      const uid = file.uid      const objKeyArr = Object.keys(this.listObj)      for (let i = 0, len = objKeyArr.length; i < len; i++) {        if (this.listObj[objKeyArr[i]].uid === uid) {          this.listObj[objKeyArr[i]].url = response.data          // this.listObj[objKeyArr[i]].url = response.files.file          this.listObj[objKeyArr[i]].hasSuccess = true          return        }      }    },    handleRemove(file) {      const uid = file.uid      const objKeyArr = Object.keys(this.listObj)      for (let i = 0, len = objKeyArr.length; i < len; i++) {        if (this.listObj[objKeyArr[i]].uid === uid) {          delImage(this.listObj[objKeyArr[i]].url).then(response => {            if (response.code !== 20000) {              this.$message('删除失败')              return            }            delete this.listObj[objKeyArr[i]]          }).catch(err => {            console.log(err)          })          return        }      }    },    beforeUpload(file) {      const _self = this      const _URL = window.URL || window.webkitURL      const fileName = file.uid      this.listObj[fileName] = {}      return new Promise((resolve, reject) => {        const img = new Image()        img.src = _URL.createObjectURL(file)        img.onload = function() {          _self.listObj[fileName] = { hasSuccess: false, uid: file.uid, width: this.width, height: this.height }        }        resolve(true)      })    }  }}</script><style lang="scss" scoped>.editor-slide-upload {  margin-bottom: 20px;  /deep/ .el-upload--picture-card {    width: 100%;  }}</style>

至此,vue-element-admin 单独上传图片实现方式就讲完了,如有任何问题或建议欢迎提issues

links


文章来源:智云一二三科技

文章标题:vue-element-admin 上传upload图片慢问题处理

文章地址:https://www.zhihuclub.com/7473.shtml

关于作者: 智云科技

热门文章

评论已关闭

3条评论

  1. Steuerwald, M In gliomas 35 and cervical 36, pancreatic 37, and colorectal cancer 38, the overexpression of PHGDH is associated with advanced TNM stage, large tumor, higher tumor grade, and shorter overall survival time, respectively

网站地图