美文网首页
vue 基于element-ui 文件 上传组件el-Uploa

vue 基于element-ui 文件 上传组件el-Uploa

作者: andcen | 来源:发表于2022-01-08 16:58 被阅读0次

    一,写在前面

    1# 虽然element的已经很好了,但是很多地方都要用每次都要写还是稍微有点麻烦,所以把element-ui的上传组件重新封装了一下,方便多次调用。(我这里因为是统一的文件服务器,所以地址直接封装在里面了,看业务,如果有需要可以封装在外面,传进来。)
    2# 记录一下方便以后使用。

    二,界面展示

    上传展示1.png

    三,组件代码展示

    组件 ImageListUpload.vue

    <template>
      <div class="images-list">
        <el-upload class="upload-demo"
         :action="uploadUrl"
         :before-upload="handleBeforeUpload"
         :on-success="handleSuccess"
         :on-error="handleUploadError"
         :on-remove="handleRemove"
         :on-exceed="handleExceed"
         :file-list="fileList"
         :multiple="fileLimit > 1"
         :data="paramsData"
         :limit="fileLimit"
         :list-type="listType">
         <i v-if="listType === 'picture-card'" class="el-icon-plus"></i>
         <el-button v-else size="small" type="primary">点击上传</el-button>
         <div v-if="showTip" slot="tip" class="el-upload__tip">只能上传{{fileTypeName || 'jpg/png'}}文件,且不超过 {{fileSize}}MB</div>
         </el-upload>
      </div>
    </template>
    <script>
    export default {
      name:'ImageListUpload ',
      props:{
        // 值
        value: [String, Object, Array],
        // 大小限制(MB)
        fileSize: {
          type: Number,
          default: 5,
        },
        // 文件类型, 例如["doc", "xls", "ppt", "txt", "pdf"]
        fileType: {
          type: Array,
          default: () => ['png', 'jpg', 'jpeg'],
        },
        // 文件列表类型 text/picture/picture-card
        listType:{
          type: String,
          default: 'picture'
        },
        // 是否显示提示
        isShowTip: {
          type: Boolean,
          default: true
        },
        // 最大允许上传个数
        fileLimit: {
          type: Number,
          default: 99
        },
      },
      data() {
        return {
          uploadUrl: "https://xxxxxxxxxxxxxxxxxxx/upload", // 上传的图片服务器地址
          paramsData: {
             'Authorization': 'Bearer token',
             'output': 'json'
          }, // 上传携带的参数,看需求要不要
          fileList:[],
          tempFileList: [] // 因为 fileList为只读属性,所以用了一个中间变量来进行数据改变的交互。
        }
      },
      watch:{
        value: {
          handler:function(newVal,oldVa){
            this.tempFileList = newVal
          },
          immediate: true,
          deep: true
        }
      },
      computed: {
        // 是否显示提示
        showTip() {
          return this.isShowTip && (this.fileType || this.fileSize);
        },
        fileTypeName(){
          let typeName = ''
          this.fileType.forEach(item => {
            typeName += `${item},`
          })
          return typeName
        },
        fileAccept(){
          let fileAccept = ''
          this.fileType.forEach(element => {
            fileAccept += `.${element},`
          })
          return fileAccept
        }
      },
      created() {
        this.fileList = JSON.parse(JSON.stringify(this.value))
      },
      methods: {
        // 上传前校检格式和大小
        handleBeforeUpload(file) {
          // 校检文件类型
          if (this.fileType && file) {
            let fileExtension = "";
            if (file.name.lastIndexOf(".") > -1) {
              fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
            }
            const isTypeOk = this.fileType.some((type) => {
              if (file.type.indexOf(type) > -1) return true;
              if (fileExtension && fileExtension.indexOf(type) > -1) return true;
              return false;
            });
            if (!isTypeOk & file) {
              this.$message.error(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);
              return false;
            }
          }
          // 校检文件大小
          if (this.fileSize && file) {
            const isLt = file.size / 1024 / 1024 < this.fileSize;
            if (!isLt) {
              this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`);
              return false;
            }
          }
          return true;
        },
        handleUploadError(err) {
          this.$message.error("上传失败, 请重试");
        },
        // 文件个数超出
        handleExceed() {
          this.$message.error(`超出上传文件个数,请删除以后再上传!`);
        },
        // 文件上传成功的钩子
        handleSuccess(res, file, fileList){
          this.$message.success("上传成功")
          this.changeFileList(fileList)
        },
        // 文件列表移除文件时的钩子
        handleRemove(file, fileList) {
          this.changeFileList(fileList)
        },
        // 文件列表改变的时候,更新组件的v-model的文的数据
        changeFileList(fileList){
          const tempFileList = fileList.map(item=>{
            let tempItem = {
              name: item.name,
              url: item.response ? item.response.url : item.url
            }
            return tempItem
          })
          this.$emit("input", tempFileList)
        }
      },
    }
    </script>
    <style lang="scss" scoped>
    .images-list{
      border: 1px dashed #d5d5d5;
      padding: 10px;
      border-radius: 4px;
      background: #fff;
    }
    
    </style>
    

    四,使用方法

    注意文件的数据这里全部为数组,哪怕单个文件也是数组[{url:xxx,name:xxx}]

    ~~ 引入ImageListUpload ~~
    // 图片模式(照片墙)
    <ImageListUpload v-model="文件列表数组数据,[{url:xxx,name:xxx}](可用于返显,初始值应设置为空数组[])" :fileLimit="99" listType='picture-card' />
    // 图片模式(缩略图)
    <ImageListUpload v-model="文件列表数组数据,[{url:xxx,name:xxx}](可用于返显,初始值应设置为空数组[])" :fileLimit="99" listType='picture' />
    // 普通文件模式
     <ImageListUpload v-model="文件列表数组数据,[{url:xxx,name:xxx}](可用于返显,初始值应设置为空数组[])" :fileSize="80" :fileLimit="1" listType="text" :fileType='["pdf", "doc", "docx", "xls", "xlsx", "txt"]' />
    

    相关文章

      网友评论

          本文标题:vue 基于element-ui 文件 上传组件el-Uploa

          本文链接:https://www.haomeiwen.com/subject/chwecrtx.html