element upload上传图片,上传完成隐藏组件或者禁用上传

背景:

在项目开发,需要上传图片,一张或者多张。当上传1张图片时,upload组件有一张图片时,组件自带的disable=true设置为true禁用上传,就不会触发上传接口了,但是还是可以点开图片进行选择,【优化为:已经上传一张,就不可以触发选择,即不选择图片也不触发上传接口】;当一张图片的时候,通过改变upload组件的css样式隐藏组件,使用:class=" 'isActive' "通过变量控制upload组件的显示与否;当上传多张图片的时候,同上传1张的逻辑一样,只是数量不同。

 一、上传1张图片

实现效果:

结果分析:

通过组件的limit='1'属性设置为1张,并且组件的disable属性变成了true。这个时候实现的效果是:当成功上传一张图片,并且上传组件已经被禁用,不能够触发选择图片的弹框。这已经能够实现上传单张的效果了,但是项目要求,上传一张还想重新删除、再上传,这时候发现已经上传的图片只有预览,删除按钮不见了,这个时候需要想办法把删除按钮显示出来。

解决思路:

类似于自定义一张icon的绝对定位,让它显示在图片上面。

核心代码:

解决办法:

官方文档:点击访问官网

 封装的组件代码:

<el-upload
            list-type="picture-card"
            :limit="1"
            :file-list="upImgState.fileList"
            :style="{
              width: item.width || '10vw',
              height: item.width || '10vw',
            }"
            :action="item.option.importUrl"
            :data="item.option.uploadParames"
            :show-file-list="true"
            :headers="{ Authorization: store.userInfo.token }"
            :on-success="(info) => uploadSingleImg('success', info, item)"
            :on-error="(info) => uploadSingleImg('error', info)"
            :before-upload="beforeUploadSingleImg"
            :before-remove="
              (info) => beforeRemoveSingleImg('remove', info, item)
            "
            :on-preview="handlePictureCardPreview"
            accept="image/jpeg,image/png"
            :disabled="
              upImgState.fileList.length
                ? true
                : false
            "
          >
            <el-icon class="avatar-uploader-icon">
              <Plus />
            </el-icon>
            <template #file="{ file }">
              <div>
                <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)"
                  >
                    <el-icon><zoom-in /></el-icon>
                  </span>
                  <span
                    class="el-upload-list__item-delete"
                    @click="beforeRemoveSingleImg('remove', file, item)"
                  >
                    <el-icon><Delete /></el-icon>
                  </span>
                </span>
              </div>
            </template>
          </el-upload>
          <el-dialog v-model="upImgState.dialogVisible">
            <img
              :src="upImgState.dialogImageUrl"
              alt="Preview Image"
              style="width: 100%"
            />
          </el-dialog>
<script>
const uploadSingleImg = (state, info, item) => {
  if (state === "success") {
    const { data: resData } = info;
    item.getRowInfo(resData);
    upImgState.dialogImageUrl = BASEUrl + "/file/" + resData;
    const _fileList = upImgState.fileList || [];
    _fileList.unshift({ url: upImgState.dialogImageUrl });
    upImgState.fileList = _fileList;
  }
  ElMessage({
    type: state,
    message: `单个文件上传${state === "success" ? "成功" : "失败"}`,
  });
};
const beforeUploadSingleImg = (rawFile) => {
  if (!rawFile) return false;
  if (rawFile.type !== "image/jpeg" && rawFile.type !== "image/png") {
    ElMessage.error("文件类型须为图片格式!");
    return false;
  } else if (rawFile.size / 1024 / 1024 > 10) {
    ElMessage.error("文件大小须小于10MB!");
    return false;
  }
  return true;
};
const beforeRemoveSingleImg = (state, info, item) => {
  if (state === "remove") {
    console.log("info", info);
    const _fileName = info.url.split("/")[info.url.split("/").length - 1];
    const _fileType = item.option.uploadParames.fileType;
    item.removeImg({
      title: "删除图片",
      fileName: _fileName,
      fileType: _fileType,
    });
    upImgState.fileList = [];
  }
  return true;
};
const upImgState = reactive({
  dialogVisible: false, //预览弹框显示与否
  dialogImageUrl: "",
  fileList: [],
});
const handlePictureCardPreview = (file) => {
  upImgState.dialogImageUrl = file.url || BASEUrl + file.url;
  upImgState.dialogVisible = true;
};


</script>

如何使用封装的组件:

//没有写完,只只是个传参示例
{
    type: "uploadSingleImg",
    label: "渡船图片",
    key: "photo",
    option: {
      uploadParames: {
        fileType: 2,
      },
      img_bg: "table/upload.png",
      info: "upload",
      text: "上传",
      importUrl: BASEUrl + "/data/file/upload",
    },
    width: "100%",
    getRowInfo: (data) => {
      console.log("上传图片的结果", data);
      state.formItemsVal.photo = data;
    },
    removeImg: (data) => {
      console.log("删除图片的结果", data);
      api.fileApi
        .deleteFile({ fileName: data.fileName, fileType: data.fileType })
        .then((res) => {
          if (res.status === 200 && res.data.code === 200) {
            ElMessage({
              type: "success",
              message: "删除成功",
            });
          } else {
            ElMessage({
              type: "error",
              message: res.data.message || "删除失败",
            });
          }
        })
        .catch((err) => {
          console.log(err);
        });
    },
  },

备注:

上传图片这里我选用的是自动上传,所以当我选中一张图片就会触发上传接口,根据接口就会返回一个{},包括但不限于:图片的相对路径、图片的名称等等。

这里需要注意的是图片相对路径,要显示在界面上,需要图片代理,最好使用BASEUrl,根据 const BASEUrl = import.meta.env.VITE_USER_NODE_ENV === 'development' ?判断开发环境还是生产环境,进行拼接访问路径。

图片新增,需要拼接访问前缀【也可以不要,但是要预览就需要】;图片复现,需要拼接访问前缀,图片编辑接口,需要去掉访问前缀。

图片删除接口,需要对应的文件名+文件类型,依据接口文档。

图片回显,需要拼接前缀:

 

编辑操作:

 删除操作:

图片删除再上传:

解决方式:

在调删除接口的时候,正确传参。核心代码如下:

二、上传多张图片

效果展示:

上传多张图片的时候,最后一张图片也没有删除按钮,最后一张只有预览按钮:

解决方式:

同一张图片一样:

三、上传一张图片后,隐藏upload组件

效果实现:

核心代码:

        <el-upload
            :auto-upload="false"
            list-type="picture-card"
            :on-preview="handlePictureCardPreview"
            :on-change="uploadSingleImg"
            :limit="5"
            :file-list="upImgState.fileList"
            :class="upImgState.fileList.length !== 0 ? 'isHidden' : ''"
          >
            <el-icon v-if="upImgState.fileList.length == 0">
              <Plus />
            </el-icon>
          </el-upload>

          <el-dialog v-model="upImgState.dialogVisible">
            <img
              :src="upImgState.dialogImageUrl"
              alt="Preview Image"
              style="width: 100%"
            />
          </el-dialog>


//css样式
.isHidden{
    .el-upload--picture-card {
        display: none;
    }
    :deep(.el-upload--picture-card) {
        display: none;
    }
}

写在最后:

两种方式限制上传的数量,当限制1张的时候,使用upload组件自带的disable属性禁用组件;使用动态class绑定一个变量控制是否显示upload上传框。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值