element el-upload 一次上传单张/多张图片(多选)


前言

这是使用element-ui中的el-upload进行上传的,但是吧,预览是自定义的组件,所以多选会有些麻烦,因为file-list的参数,具体参考例子来讲吧


一、单张图片的上传

// 这是自定义的图片预览的组件,pictureList就是上传的图片
    <image-list :pictureList.sync="pictureList"
                     @preview="onPreview"></image-list>
    // 这是上传的标识,当图片大于9张就不允许其上传了,就没有上传的按钮啦。下面的代码也会调用on-exceed,有提示
    <el-upload v-if="pictureList.length < 9"
               ref="upload"
               class="image-upload"
               :limit="limit"
               :accept="accept"
               :multiple="multiple"
               :action="uploadUrl"
               :headers="headers"
               :data="data"
               :show-file-list="showFileList"
               :file-list="pictureList"
               list-type="picture-card"
               :before-upload="handleBeforeUpload"
               :on-exceed="handleExceed"
               :on-success="handleSuccess">
      <i class="el-icon-plus"
         v-loading.fullscreen.lock="uploading"
         element-loading-text="正在上传,请稍等..."></i>
      <!--<span slot="tip" class="el-upload-tip">只能上传 jpg/png 文件,且不超过 {{ maxSize }} MB</span>-->
    </el-upload>


// 图片上传之前
    handleBeforeUpload(file) {
      let self = this;
      // 文件类型
      const typeIsOk = file.type == 'image/jpeg' || file.type == 'image/png';
      // 文件大小
      const sizeIsOk = file.size / 1024 / 1024 < self.maxSize;
      if (typeIsOk && sizeIsOk) {
        self.uploading = true;
      }
      if (!typeIsOk) {
        self.$message.error('只能上传 jpg/png 文件!');
      }
      if (!sizeIsOk) {
        self.$message.error('单个图片大小不能超过 ' + self.maxSize + 'MB!');
      }
      return typeIsOk && sizeIsOk;
    },
    // 文件超出个数限制时
    handleExceed() {
      let self = this;
        self.$message.error('最多只能上传' + self.limit + '张图片!');
    },
    // 图片上传成功
    handleSuccess(response) {
      let self = this;
      self.uploading = false;
      if (response.success) {
        if (Object.keys(response.result).length > 0) {
          let picture = response.result;
          if (JSON.stringify(self.pictureList).indexOf(JSON.stringify(picture)) == -1) {
            self.pictureList.push(picture);
          }
          self.$message.success('图片上传成功!');
          // 图片列表
          self.$emit('update:pictureList', self.pictureList);
          // 图片上传成功
          self.$emit('uploadSuccess', self.pictureList);
        }
      } else {
        self.$message({
          showClose: true,
          duration: 10000,
          message: response.data + '!',
          type: 'error'
        });
        // 清空文件列表
        self.$refs['upload'].clearFiles();
        // 更新上传的文件
        self.$emit('update:pictureList', []);
      }
    },
    // 预览图片
    onPreview(pictureList) {
      let self = this;
      self.$emit('previewImage', pictureList);
    }

二、一次上传多张图片

html的代码都是类似的,唯一的区别是file-list,其参数名不能跟图片列表的参数名一致,不然图片列表不能进行push,从而不能预览。
因为项目需要,有新增和编辑,所以需要一个editUpload进行图片的深拷贝,作为编辑的时候已上传的数据,以此来控制总数据量便于数量限制

代码如下:


// uploadArr每次打开新增/编辑都要传空过来,就相当于清空fileList
:file-list='uploadArr'

// 需要写在handleBeforeUpload里面
// 获取第一次进来的数据,用于统计已上传的数据,即编辑
      if (this.editFirstFlag1) {
      // editUpload  仅用以计算用户可上传的图片数量;需要传给图片列表(删除再图片列表组件中进行)并实时更新
        this.editUpload =  this.pictureList.map(i => JSON.parse(JSON.stringify(i)))
        
        this.editFirstFlag1 = false
      }
// 文件超出个数限制时
    handleExceed() {
      let self = this;
      if(this.editLength == 0){
        self.$message.error('最多只能上传' + self.limit + '张图片!');
      }else {
        self.$message.error('已有'+this.editLength+'张图片,此次最多只能上传' + self.limit + '张图片!');
      }
    },

    mounted() {
    // 每次调用组件都要执行,使用v-if强制组件更新;所以editFirstFlag必须是父组件传递过来的true
    this.editFirstFlag1 = this.editFirstFlag
  },

  computed: {
    editLength(){
      // 编辑的时候已上传的数据
      return this.editUpload.length
    },
  },

  watch: {
    editLength:{
      immediate:true,
      handler(newVal, oldVal) {
        let self = this
        // 限制图片上传数量的
        this.limit = 9 - newVal
  
        // console.log(this.limit)
      }
    }
  },  

### 使用 `el-upload` 组件上传单张图片到阿里云 OSS 的解决方案 #### 安装依赖 为了能够使用阿里云 OSS 进行文件上传,需先安装 `ali-oss` 插件。这可以通过 npm 来完成。 ```bash npm install ali-oss --save ``` 此命令会将所需 SDK 添加到项目中以便后续调用[^1]。 #### 创建 OSS 实例配置文件 接着,在项目的合适位置创建名为 `oss.js` 文件用于初始化并返回一个新的 OSS Client 实例: ```javascript // oss.js import OSS from 'ali-oss'; export default function createOssClient(config) { return new OSS({ ...config, // 可参数设置区域、访问密钥ID、私钥以及bucket名称等必要信息 }); } ``` 上述代码片段展示了如何通过传入适当配置来实例化一个客户端对象[^3]。 #### Vue 组件集成 对于基于 Element UI 开发的应用程序来说,可以直接利用其提供的 `el-upload` 组件来进行文件择和提交操作。下面是一个简单的例子说明怎样结合前面定义好的 OSS 工具类实现图片上传功能: ```html <template> <div class="upload-demo"> <el-upload :action="''" list-type="picture-card" :auto-upload="false" :on-change="handleChange" :before-upload="handleBeforeUpload" :limit="1" ref="uploadRef" > <i slot="default" class="el-icon-plus"></i> <div slot="file" slot-scope="{ file }"> <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" /> <span class="el-upload-list__item-actions"> <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)"> <i class="el-icon-zoom-in"></i> </span> <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleDownload(file)"> <i class="el-icon-download"></i> </span> <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)"> <i class="el-icon-delete"></i> </span> </span> </div> </el-upload> <!-- 图片预览对话框 --> <el-dialog :visible.sync="dialogVisible"> <img width="100%" :src="dialogImageUrl" alt="" /> </el-dialog> </div> </template> <script> import createOssClient from './path/to/your/oss'; // 替换成实际路径 export default { data() { return { dialogImageUrl: '', dialogVisible: false, client: null, // 存储OSS客户端实例 }; }, methods: { async initOssClient() { const config = {}; // 填写您的STS临时凭证或其他认证方式获取的信息 this.client = await createOssClient(config); }, handleBeforeUpload(file) { // 在这里可以根据需求做些前置处理比如尺寸校验或者格式过滤 console.log('准备上传:', file); // 返回 true 表示允许继续执行默认行为;如果想阻止则应显式地return false; return true; }, handleChange(file, fileList) { if (fileList.length > 0 && !this.disabled) { let f = fileList[fileList.length - 1]; this.uploadFile(f.raw).then((res) => { console.log(res); }).catch(err => { console.error(err.message || err); }) } }, uploadFile(rawFile) { return new Promise(async(resolve, reject)=>{ try{ const result = await this.client.put(`/${Date.now()}-${rawFile.name}`, rawFile); resolve(result); } catch(error){ reject(error); } }); } // 其他方法... }, }; </script> ``` 这段代码实现了基本的功能逻辑,包括但不限于: - 初始化 OSS 客户端; - 控制文件的择过程; - 自定义上传前后的钩子函数; -定的文件发送给服务器保存,并接收响应数据[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值