图片上传:

<template>
  <div class="upload-pic">
    <el-upload
      class="upload-demo"
      :action="uploadFdfsFileUrl"
      :headers="requestHeader"
      list-type="picture-card"
      name="file"
      :before-upload="beforeAvatarUpload"
      :on-preview="handlePictureCardPreview"
      :on-remove="handleRemove"
      :before-remove="beforeRemove"
      :on-success="handleSuccess"
      :on-error="handleError"
      :multiple="multiple"
      :limit="limitNum"
      :on-exceed="handleExceed"
      :file-list.sync="picWebUrlList"
    >
      <i class="el-icon-plus"></i>
    </el-upload>
    <el-dialog :visible.sync="dialogVisible">
      <img width="100%" :src="dialogImageUrl" alt="">
    </el-dialog>
  </div>
</template>
  import { mapGetters, mapActions } from 'vuex'
  import { getToken } from '@/utils/auth'
  export default {
    name: 'UploadPic',
    props: {
      isEdit: {
        type: Boolean,
        default: false
      },
      // 是否多选
      multiple: {
        type: Boolean,
        default: true
      },
      // 文件列表
      fileList: {
        type: Array,
        default: () => []
      },
      // 限制上传个数
      limitNum: {
        type: Number,
        default: null
      }
    },
    data() {
      return {
        // 附件上传请求头
        requestHeader: '',
        // 图片上传路径
        picUploadList: [],
        // 图片回显路径
        picWebUrlList: [],
        // 预览路径
        dialogImageUrl: '',
        // 预览弹框
        dialogVisible: false,
        // 删除图片下标
        delIndex: null
      }
    },
    computed: {
      ...mapGetters([
        'uploadFdfsFileUrl'
      ])
    },
    watch: {},
    /**
     * 生命周期函数--el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子
     */
    mounted: function() {},
    created() {
      // 设置文件按上传请求头
      this.requestHeader = { 'Authorization': 'Bearer ' + getToken('token') }
    },
    methods: {
      ...mapActions([
        'download'
      ]),
      refreshPicData(value) {
        this.picUploadList = value
        this.getWebUrlList()
      },
      // 图片回显数组
      getWebUrlList() {
        let webUrlList = []
        if (this.picUploadList.length > 0) {
          this.picUploadList.forEach((item, index) => {
            // 获取图片 web 地址
            this.$store.dispatch('dictionary/getWebFileUrl', item.url).then(response => {
              const fileObj = {
                index: index,
                name: '',
                url: response.data
              }
              webUrlList.push(fileObj)
            })
          })
          this.picWebUrlList = webUrlList
        }
      },
      // 图片格式及大小限制
      beforeAvatarUpload(file) {
        const isJPG = file.type === 'image/jpg'
        const isJPEG = file.type === 'image/jpeg'
        const isGIF = file.type === 'image/gif'
        const isPNG = file.type === 'image/png'
        const isBMP = file.type === 'image/bmp'
        const isLt2M = file.size / 1024 / 1024 < 2
        if (!isJPG && !isJPEG && !isGIF && !isPNG && !isBMP) {
          this.$message.error('上传图片必须是JPG/JPEG/GIF/PNG/BMP 格式!')
        }
        if (!isLt2M) {
          this.$message.error('上传图片大小不能超过 2MB!')
        }
        return (isJPG || isJPEG || isBMP || isGIF || isPNG) && isLt2M
      },
      // 点击预览图标,预览图片
      handlePictureCardPreview(file) {
        this.dialogImageUrl = file.url
        this.dialogVisible = true
      },
      // 文件列表移除文件时的钩子
      handleRemove(file, fileList) {
        if (this.isEdit) {
          this.picUploadList.splice(this.delIndex, 1)
          this.$emit('update:fileList', this.picUploadList)
        } else {
          const fileArr = []
          fileList.forEach(item => {
            if (item.response) {
              const fileObj = {
                name: item.name,
                url: item.response.data
              }
              fileArr.push(fileObj)
            } else {
              fileArr.push(item)
            }
          })
          this.$emit('update:fileList', fileArr)
        }
      },
      // 删除文件之前的钩子
      beforeRemove(file, fileList) {
        fileList.forEach((item, index) => {
          if (file.url === item.url) {
            this.delIndex = index
          }
        })
        return this.$confirm('', `确定移除 ${file.name}?`, { customClass: 'del-dialog' })
      },
      // 文件上传成功时的钩子
      handleSuccess(response, file, fileList) {
        if (response.code === '1') {
          if (this.isEdit) {
            const fileObj = {
              index: this.picUploadList.length,
              name: file.name,
              url: response.data
            }
            this.picUploadList.push(fileObj)
            this.$emit('update:fileList', this.picUploadList)
          } else {
            const fileArr = []
            fileList.forEach(item => {
              if (item.response) {
                const fileObj = {
                  name: item.name,
                  url: item.response.data
                }
                fileArr.push(fileObj)
              } else {
                fileArr.push(item)
              }
            })
            this.$emit('update:fileList', fileArr)
          }
        } else {
          this.$message({
            message: `${file.name} 上传失败,请重新再试`,
            type: 'error',
            duration: 2000
          })
        }
      },
      // 文件上传失败时的钩子
      handleError(err, file, fileList) {
        console.log(err)
        this.$message({
          message: `${file.name} 上传失败,请重新再试`,
          type: 'error',
          duration: 2000
        })
      },
      // 文件超出个数限制时的钩子
      handleExceed(files, fileList) {
        this.$message.warning(`当前限制选择 ${this.limitNum} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`)
      }
    }
  }

父组件引用:<upload-pic ref="refreshData" :file-list.sync="formData.picList" :limit="1" :is-edit="isEdit"></upload-pic>

在编辑图片时,将编辑图片的数组传递给图片上传组件,否则不能回显父组件拿到图片数据后,通过调用图片上传组件内的 refreshPicData 方法,传递图片数据。

 

 


 


文件上传:

<template>
  <div class="upload-file">
    <el-upload
      class="upload-demo"
      :action="uploadFdfsFileUrl"
      :headers="requestHeader"
      name="file"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :before-remove="beforeRemove"
      :on-success="handleSuccess"
      :on-error="handleError"
      :multiple="multiple"
      :limit="limitNum"
      :on-exceed="handleExceed"
      :file-list.sync="fileList"
    >
      <el-button class="dashed-btn" icon="el-icon-upload" size="small">{{ btnTxt }}</el-button>
      <div slot="tip" class="el-upload__tip">{{ tipTxt }}</div>
    </el-upload>
  </div>
</template>
  import { mapGetters, mapActions } from 'vuex'
  import { getToken } from '@/utils/auth'
  export default {
    name: 'UploadFile',
    props: {
      // 是否多选
      multiple: {
        type: Boolean,
        default: true
      },
      // 文件列表
      fileList: {
        type: Array,
        default: () => []
      },
      // 限制上传个数
      limitNum: {
        type: Number,
        default: null
      },
      // 按钮文字
      btnTxt: {
        type: String,
        default: '上传附件'
      },
      // tip 提示
      tipTxt: {
        type: String,
        default: ''
      }
    },
    data() {
      return {
        // 附件上传请求头
        requestHeader: ''
        // 限制文件数量
        // limitNum: ''
        // 文件列表
        // fileList: []
      }
    },
    computed: {
      ...mapGetters([
        'uploadFdfsFileUrl'
      ])
    },
    watch: {},
    /**
     * 生命周期函数--el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子
     */
    mounted: function() {},
    created() {
      // 设置文件按上传请求头
      this.requestHeader = { 'Authorization': 'Bearer ' + getToken('token') }
    },
    methods: {
      ...mapActions([
        'download'
      ]),
      // 点击文件列表中已上传的文件时的钩子,下载文件
      handlePreview(file) {
        console.log(file)
        // const param = {
        //   fileUrl: file.url
        // }
        // this.$store.dispatch('dictionary/downLoad', param).then(response => {
        //   console.log(response)
        //   let fileName = localStorage.fileName
        //   fileName = decodeURI(fileName.substr(fileName.indexOf('=') + 1))
        //   const paramData = {
        //     data: response,
        //     title: '天津园区电梯监控.xlsx'
        //   }
        //   this.download(paramData)
        // })
      },
      // 文件列表移除文件时的钩子
      handleRemove(file, fileList) {
        const fileArr = []
        fileList.forEach(item => {
          if (item.response) {
            const fileObj = {
              name: item.name,
              url: item.response.data
            }
            fileArr.push(fileObj)
          } else {
            fileArr.push(item)
          }
        })
        this.$emit('update:fileList', fileArr)
      },
      // 删除文件之前的钩子
      beforeRemove(file, fileList) {
        return this.$confirm('', `确定移除 ${file.name}?`, { customClass: 'del-dialog' })
      },
      // 文件上传成功时的钩子
      handleSuccess(response, file, fileList) {
        if (response.code === '1') {
          const fileArr = []
          fileList.forEach(item => {
            if (item.response) {
              const fileObj = {
                name: item.name,
                url: item.response.data
              }
              fileArr.push(fileObj)
            } else {
              fileArr.push(item)
            }
          })
          this.$emit('update:fileList', fileArr)
        } else {
          this.$message({
            message: `${file.name} 上传失败,请重新再试`,
            type: 'error',
            duration: 2000
          })
        }
      },
      // 文件上传失败时的钩子
      handleError(err, file, fileList) {
        console.log(err)
        this.$message({
          message: `${file.name} 上传失败,请重新再试`,
          type: 'error',
          duration: 2000
        })
      },
      // 文件超出个数限制时的钩子
      handleExceed(files, fileList) {
        this.$message.warning(`当前限制选择 ${this.limitNum} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`)
      }
    }
  }

父组件引用:<upload-file :file-list.sync="formData.fileList" ></upload-file>

 

posted on 2020-06-04 14:33  丶小馨  阅读(3502)  评论(0编辑  收藏  举报