一般这种上传文件相关的业务,都需要两个url,一个是用来本地预览的完全url(包含http那种),另一个是用来前后台通讯的数据url(一般只有一个文件名字,这样能避免域名和服务器更换带来的图片路径404bug),有些时候上传的文件名也需要两个,用途和url类似,因为,有时候借助七牛云等cdn的时候,上传图片到人家的服务器的时候,会根据人家的命名规则改变文件名称,不利于前台页面显示。

<template>
  <div class="uploader">
    <div class="uploader-container" :style="{backgroundImage: 'url(' + pictureUrl + ')'}">
        <i class="el-icon-plus" :class="showIcon? 'show': 'hide'"></i>
    </div>
    <input type="file" class="uploader-action" :model="pictureUrl" @change="fileChange" />
  </div>
</template>

<script>
  import axios from "axios";
  import {axiosProxyFiles} from "@/api/tool"
  export default {
    props:{
      default: '', // 默认显示的图片
      index: '' // 如果一个页面里用到了多个图片上传组件,这个参数用来区别他们
    },

    data() {
      return {
        pictureUrl: '', // 用来预览的图片路径
        showIcon: true, // 有图片的时候显示图片,没图片的时候显示成一个加号
        picturePath: '' // 传给接口的那个图片路径
      };
    },


    methods: {
      fileChange (e) {
        let file = e.target.files[0]
        let filename = e.currentTarget.files[0]
        var formData = new FormData();
        formData.append("file", file);

        // 如果资源传到自己的服务器上,需要以上四行代码,转换一下文件格式,如果直接上传文件到cdn,则不需要
        let url = YOURURL
        axiosProxyFiles.post(url, formData)
        .then(res=>{
          if(res.data.errorCode=='0'){
            this.successMessage('文件上传成功')
            this.pictureUrl = res.data.data.url
            this.picturePath = res.data.data.path
            this.showIcon = false
            if(this.index) {
              this.$emit('change', this.pictureUrl, this.index, this.picturePath)
            } else {
              this.$emit('change', this.pictureUrl)
            }
          }
          else {
            if(res.data.errorMessage) {
              this.errorMessage(res.data.errorMessage)
            } else {
              this.errorMessage('文件上传失败')
            }
          }
        })
        .catch(err=>{console.log(err)})
      },
    },
    mounted () {
      if(this.default != undefined) {
        if(this.default == '') {
          this.showIcon = true
        } else {
          this.showIcon = false
        }
        this.pictureUrl = this.default
      } else {
        this.showIcon = true
      }
    }

};
</script>

// 本demo相关样式用scss编写,注意style后面的lang=‘scss’

<style lang='scss' scoped>
  .uploader {
    position: relative;
  }
  .uploader-container {
    background-color: #fbfdff;
    border: 1px dashed #c0ccda;
    border-radius: 6px;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    width: 148px;
    height: 148px;
    line-height: 146px;
    vertical-align: top;
    text-align: center;
    background-size: cover;
    background-repeat: no-repeat;
    background-position: center;
    i {
      font-size: 28px;
      color: #8c939d;
    }
  }

  .uploader-action {
    position: absolute;
    top: 0;
    opacity: 0;
    display: block;
    width: 148px;
    height: 148px!important;
  }

  .hide {
    visibility: hidden;
  }

  .show {
    visibility: visible;
  }
</style>

下面是axiosProxyFiles的封装

import axios from "axios"

let axiosProxyFiles = axios.create({
  headers: {
    'X-Requested-With': 'XMLHttpRequest',
    'Content-Type': 'multipart/form-data'
  },

// 具体的header内容是啥,取决于你们公司的后台小哥姐
  withCredentials:true, // 开启cache模式
})

export {
    axiosProxyFiles
}

Logo

前往低代码交流专区

更多推荐