关于vue-element-admin的采坑记录-upload组件图片上传问题

个人博客里部分内容用到了图片上传

那就需要用到vue-element-admin中的upload组件

首先我们需要在需要到图片上传的vue文件里引入upload组件 并使用标签的形式使用该组件 通过v-model绑定image属性

<template>
  <div class="createPost-container">
    <Upload v-model="image"/>
  </div>
</template> 
​
<script>
    import Upload from '@/components/Upload/SingleImage3'
    
    export default {
        name: 'EssayDetail',
        components: {Upload},
        data() {
            image:''
        },
    }
</script>

  


这样组件就能够为我们做上传图片的功能

这样的图片上传使用的是upload默认的上传,而它内部做的事情则是将我们上传的文件转为image base64编码

返回的结果可能是

data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD//gAQTGF2YzU4LjI3LjEwMAD/2wBDAAgCAgICAgICAgICAgMDAwMDAwMDAwMDAwMDAwMEBAQDAwMDAwMDBAQEBAQEBAQEBAQEBAUFBQYGBQUHBwcICAr/xAD9AAEAAgMBAQEAAAAAAAAAAAAAAgEGBAMFBwgBAQEBAQEBAQEAAAAAAAAAAAABAgMEBQYHEAABAwMCAwUEBQYJBAoIDBcBAAIDBAUREgYhBzFBYVEIEyKBFHEyFaGR8DMjwUKxUlNykuHRYgkkFoIXVPElQ6JVpLLSNNQYtHRWczU34pVElNODY+Q2ZrV1J9W25cTFw8KT..........................(后面省略1万个字符)

  

或者更长的Base64编码

然后再将这么长的一条编码存入到数据库,很显然这么长的编码已经超出了预算 虽然数据库字段啊可以用varchar、text、longtext这样的类型但早已跟我们预期的不符,如果将这么长的编码存入到数据库很显然影响查询效率

那唯一的方式就是通过upload这个组件的源码进行修改

以上面引入的Upload/SingleImage3为例 打开SingleImage3.vue文件

<template>
  <div class="upload-container">
    <el-upload
      :data="dataObj"
      :multiple="false"
      :show-file-list="false"
      :on-success="handleImageSuccess"
      class="image-uploader"
      drag
      action="https://httpbin.org/post"
    >
      <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>
通过element-ui的官方文档阅读可知action="https://httpbin.org/post" 这个属性,这是图片的上传地址,并绑定了文件上传成功时的钩子 :on-success="handleImageSuccess"

接着查看handleImageSuccess这个方法

export default {
  name: 'SingleImageUpload3',
  props: {
    value: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      tempUrl: '',
      dataObj: { token: '', key: '' }
    }
  },
  computed: {
    imageUrl() {
      return this.value
    }
  },
  methods: {
    rmImage() {
      this.emitInput('')
    },
    emitInput(val) {
      this.$emit('input', val)
    },
    handleImageSuccess(file) {
      this.emitInput(file.files.file)
    },
    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)
        })
      })
    }
  }
}

  

而关于on-success在elementUI官网中的解释是

参数 说明 类型 可选值 默认值
on-success 文件上传成功时的钩子 function(response, file, fileList)

on-success绑定的handleImageSuccess函数中只有file 这个参数 ,显然这个函数可以再多加一个response参数

response是上传成功的回调,我们可以通过后端实现一个图片上传接口把action属性该为我们自己实现的图片上传接口,返回一条json

我后端定义的接口是 /pic/upload 后台返回的数据是json数据格式为,(根据自己情况定义json结构)

{
    "success":true,
    "code":200,
    "message":"上传成功",
    "data":"(上传成功的图片地址)"
}

  

并将handleImageSuccess改为

handleImageSuccess(res, file) {
      this.emitInput(res.data)
}

  

 

然后该方法调用了emitInput()方法传入了一个值 这个方法又执行了this.$emit('input', val)

vue中 关于$emit的用法 1、父组件可以使用 props 把数据传给子组件。 2、子组件可以使用 $emit 触发父组件的自定义事件。

vm.$emit( event, arg ) //触发当前实例上的事件

vm.$on( event, fn );//监听event事件后运行 fn;

具体使用还是多学习Vue吧

最后 handleImageSuccess中this.emitInput(res.data)这条语句

最终返回的就是上传图片的url并回显为upload 组件上的图片

 

步骤

  1. 修改action属性为自己实现的接口,定义好返回的json,把图片存在json里返回给前端,下面的response参数要用到

  2. 在handleImageSuccess中添加response 将 this.$emit('input', val)修改为 this.emitInput(res.data) res.data为图片地址

猜你喜欢

转载自www.cnblogs.com/Esummer/p/12424157.html