el-upload上传组件二次封装-数据回显-demo

组件 -组件内回显

<template>
  <el-upload
    ref="uploadRef"
    v-model:file-list="modelValue"
    action=""
    :limit="1"
    list-type="picture-card"
    :auto-upload="true"
    :on-exceed="onExceed"
    :on-change="handleChange"
    :before-upload="onBefore"
    :http-request="uploadBpmn"
  >
    <el-icon><IconifyIconOffline :icon="Plus" /></el-icon>
    <template #tip>
      <div class="el-upload__tip">只能上传jpeg/jpg/png文件</div>
    </template>
    <template #file="{ file }">
      <div>
        <!-- <img class="el-upload-list__item-thumbnail" :src="modelValue[0].url" /> -->
        <img class="el-upload-list__item-thumbnail" :src="file.url" />
        <span class="el-upload-list__item-actions">
          <span
            v-if="!disabled"
            class="el-upload-list__item-delete"
            @click="handleRemove(file)"
          >
            <el-icon><IconifyIconOffline :icon="Delete" /></el-icon>
          </span>
        </span>
      </div>
    </template>
  </el-upload>
</template>

<script setup>
defineOptions({
  name: "HElUpload"
});
import { ref, reactive, computed, defineProps, defineEmits } from "vue";
import Plus from "@iconify-icons/ep/plus";
import Delete from "@iconify-icons/ep/delete";
import { message } from "@/utils/message";
import { uploadParamUpload } from "@/api/launchpad";
const props = defineProps({
  modelValue: {
    type: String,
    default: () => ""
  }
});

const emits = defineEmits(["update:modelValue"]);

const modelValue = computed({
  get() {
    return [
      {
        url: props.modelValue
      }
    ];
  },
  set(val) {
    emits("update:modelValue", val);
  }
});

const uploadRef = ref();
const disabled = ref(false);
// 文件状态改变时
const handleChange = (response, file, fileList) => {
  console.log("handleChange", response, file, fileList);
  // modelValue.value = response.url;
};

const uploadBpmn = val => {
  console.log("uploadBpmn", val);
};
/** 上传文件前校验 */
const onBefore = file => {
  console.log("onBefore", file);

  if (!["image/jpeg", "image/png", "image/jpg"].includes(file.type)) {
    message("只能上传图片");
    return false;
  }
  const isExceed = file.size / 1024 / 1024 > 4;
  if (isExceed) {
    message(`单个图片大小不能超过4MB`);
    return false;
  }
  getUploadParamUpload(file);
};
/** 超出最大上传数时触发 当超出限制时*/
const onExceed = () => {
  message("最多上传1张图片,请先删除在上传");
};
const handleRemove = file => {
  console.log("handleRemove", file);
  modelValue.value = "";
  uploadRef.value.clearFiles();
};

// 获取头像上传参数
const getUploadParamUpload = async file => {
  try {
    let params = {
      contentType: file.type || "image/png"
    };
    const {
      data: { data }
    } = await uploadParamUpload(params);
    console.log("getUploadParamUpload", data);
    uploadImage(data, file);
  } catch (error) {
    console.log("getUploadParamUpload", error);
  }
};

// 上传图片
const uploadImage = async (xhrData, file) => {
  console.log("uploadImage", xhrData, file);
  try {
    // const formData = new FormData();
    // for (const key in xhrData.param) {
    //   const value = xhrData.param[key];
    //   formData.append(key, value);
    // }
    // formData.append("file", file.raw);
    // // console.log(xhrData.param, formData.get('file'), 9898);
    // let config = {
    //   method: "post",
    //   // maxBodyLength: Infinity,
    //   url: xhrData.uploadUrl,
    //   data: formData,
    //   headers: {
    //     "Content-Type": "multipart/form-data"
    //   }
    // };
    // const res = await axios.request(config);
    // modelValue.value = xhrData.accessUrl;
    modelValue.value =
      "https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100";
    console.log("uploadImage", res);
  } catch (error) {
    console.log("uploadImage", error);
  }
};
</script>

<style scoped lang="scss">
.hide {
  .el-upload--picture-card {
    display: none;
  }
}
</style>

使用

<HElUpload v-model="form.logo" />

自定义缩略图展示区域


<template>
  <div class="imglist" v-if="modelValue">
    <img class="imglist-img" :src="modelValue" />
    <span class="imglist-actions">
      <span class="imglist-delete" @click="handleRemove()">
        <el-icon><IconifyIconOffline :icon="Delete" /></el-icon>
      </span>
    </span>
  </div>
  <!-- v-model:file-list="modelValue" -->
  <el-upload
    v-else
    ref="uploadRef"
    action=""
    :limit="limit"
    list-type="picture-card"
    :auto-upload="true"
    :on-exceed="onExceed"
    :on-change="handleChange"
    :before-upload="onBefore"
    :http-request="uploadBpmn"
  >
    <el-icon><IconifyIconOffline :icon="Plus" /></el-icon>
    <template #tip>
      <div class="el-upload__tip">只能上传jpeg/jpg/png文件</div>
    </template>
    <!-- <template #file="{ file }">
      <div>
        <img class="el-upload-list__item-thumbnail" :src="file.url" />
        <span class="el-upload-list__item-actions">
          <span
            v-if="!disabled"
            class="el-upload-list__item-delete"
            @click="handleRemove(file)"
          >
            <el-icon><IconifyIconOffline :icon="Delete" /></el-icon>
          </span>
        </span>
      </div>
    </template> -->
  </el-upload>
</template>

<script setup>
defineOptions({
  name: "HElUpload"
});
import { ref, reactive, computed, defineProps, defineEmits } from "vue";
import Plus from "@iconify-icons/ep/plus";
import Delete from "@iconify-icons/ep/delete";
import { message } from "@/utils/message";
import { uploadParamUpload } from "@/api/launchpad";
const props = defineProps({
  modelValue: {
    type: String,
    default: () => ""
  },
  limit: {
    type: Number,
    default: 1
  }
});

const emits = defineEmits(["update:modelValue"]);

const modelValue = computed({
  get() {
    return props.modelValue;
    // [
    //   {
    //     url: props.modelValue
    //   }
    // ];
  },
  set(val) {
    emits("update:modelValue", val);
  }
});

const uploadRef = ref();
const disabled = ref(false);
// 文件状态改变时
const handleChange = (response, file, fileList) => {
  console.log("handleChange", response, file, fileList);
  // modelValue.value = response.url;
};

const uploadBpmn = val => {
  console.log("uploadBpmn", val);
};
/** 上传文件前校验 */
const onBefore = file => {
  console.log("onBefore", file);

  if (!["image/jpeg", "image/png", "image/jpg"].includes(file.type)) {
    message("只能上传图片");
    return false;
  }
  const isExceed = file.size / 1024 / 1024 > 4;
  if (isExceed) {
    message(`单个图片大小不能超过4MB`);
    return false;
  }
  getUploadParamUpload(file);
};
/** 超出最大上传数时触发 当超出限制时*/
const onExceed = () => {
  message("最多上传1张图片,请先删除在上传");
};
const handleRemove = file => {
  console.log("handleRemove", file);
  modelValue.value = "";
  // uploadRef.value.clearFiles();
};

// 获取头像上传参数
const getUploadParamUpload = async file => {
  try {
    let params = {
      contentType: file.type || "image/png"
    };
    const {
      data: { data }
    } = await uploadParamUpload(params);
    console.log("getUploadParamUpload", data);
    uploadImage(data, file);
  } catch (error) {
    console.log("getUploadParamUpload", error);
  }
};

// 上传图片
const uploadImage = async (xhrData, file) => {
  console.log("uploadImage", xhrData, file);
  try {
    // const formData = new FormData();
    // for (const key in xhrData.param) {
    //   const value = xhrData.param[key];
    //   formData.append(key, value);
    // }
    // formData.append("file", file.raw);
    // // console.log(xhrData.param, formData.get('file'), 9898);
    // let config = {
    //   method: "post",
    //   // maxBodyLength: Infinity,
    //   url: xhrData.uploadUrl,
    //   data: formData,
    //   headers: {
    //     "Content-Type": "multipart/form-data"
    //   }
    // };
    // const res = await axios.request(config);
    // modelValue.value = xhrData.accessUrl;
    modelValue.value =
      "https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100";
    console.log("uploadImage", res);
  } catch (error) {
    console.log("uploadImage", error);
  }
};
</script>

<style scoped lang="scss">
.imglist {
  width: 148px;
  height: 148px;
  border-radius: 6px;
  overflow: hidden;
  position: relative;
  border: 1px solid var(--el-border-color);
  .imglist-img {
    width: 100%;
    height: 100%;
  }
  .imglist-actions {
    align-items: center;
    background-color: var(--el-overlay-color-lighter);
    color: #fff;
    cursor: default;
    display: inline-flex;
    font-size: 20px;
    height: 100%;
    justify-content: center;
    left: 0;
    opacity: 0;
    position: absolute;
    top: 0;
    transition: opacity var(--el-transition-duration);
    width: 100%;
    span {
      display: inline-flex;
      cursor: pointer;
    }
    &:hover {
      opacity: 1;
    }
    .imglist-delete {
    }
  }
}

.hide {
  :deep(.el-upload--picture-card) {
    display: none;
  }
}
</style>

处理后优化版-数据回显展示


<template>
  <!-- <div class="imglist" v-if="isEdit">
    <img class="imglist-img" :src="modelValue" />
    <span class="imglist-actions">
      <span class="imglist-delete" @click="handleRemove()">
        <el-icon><IconifyIconOffline :icon="Delete" /></el-icon>
      </span>
    </span>
  </div> -->
  <!-- v-model:file-list="modelValue" -->
  <el-upload
    ref="uploadRef"
    v-model:file-list="fileListData"
    action=""
    :limit="limit"
    list-type="picture-card"
    :auto-upload="true"
    :on-exceed="onExceed"
    :on-change="handleChange"
    :before-upload="onBefore"
    :http-request="uploadBpmn"
  >
    <el-icon><IconifyIconOffline :icon="Plus" /></el-icon>
    <template #tip>
      <div class="el-upload__tip">只能上传jpeg/jpg/png文件</div>
    </template>
    <template #file="{ file }">
      <div>
        <img class="el-upload-list__item-thumbnail" :src="file.url" />
        <span class="el-upload-list__item-actions">
          <span
            v-if="!disabled"
            class="el-upload-list__item-delete"
            @click="handleRemove(file)"
          >
            <el-icon><IconifyIconOffline :icon="Delete" /></el-icon>
          </span>
        </span>
      </div>
    </template>
  </el-upload>
</template>

<script setup>
defineOptions({
  name: "HElUpload"
});
import { ref, reactive, computed, defineProps, defineEmits } from "vue";
import Plus from "@iconify-icons/ep/plus";
import Delete from "@iconify-icons/ep/delete";
import { message } from "@/utils/message";
import { uploadParamUpload } from "@/api/launchpad";
import axios from "axios";
const props = defineProps({
  modelValue: {
    type: [Array, String],
    default: () => ""
  },
  limit: {
    type: Number,
    default: 1
  },
});

const emits = defineEmits(["update:modelValue"]);
const fileListData = computed(() => {
  return modelValue.value
    ? [
        {
          url: modelValue.value
        }
      ]
    : [];
});
const modelValue = computed({
  get() {
    return props.modelValue;
  },
  set(val) {
    emits("update:modelValue", val);
  }
});

const uploadRef = ref();
const disabled = ref(false);
// 文件状态改变时
const handleChange = (response, file, fileList) => {
  console.log("handleChange", response, file, fileList);
  // modelValue.value = response.url;
};

const uploadBpmn = response => {
  console.log("uploadBpmn", response);
  getUploadParamUpload(response.file);
  uploadRef.value.clearFiles();
};
/** 上传文件前校验 */
const onBefore = file => {
  console.log("onBefore", file);

  if (!["image/jpeg", "image/png", "image/jpg"].includes(file.type)) {
    message("只能上传图片");
    return false;
  }
  const isExceed = file.size / 1024 / 1024 > 4;
  if (isExceed) {
    message(`单个图片大小不能超过4MB`);
    return false;
  }
};
/** 超出最大上传数时触发 当超出限制时*/
const onExceed = () => {
  message("最多上传1张图片,请先删除在上传");
};
const handleRemove = file => {
  console.log("handleRemove", file);
  modelValue.value = "";
  uploadRef.value?.clearFiles();
};

// 获取头像上传参数
const getUploadParamUpload = async file => {
  try {
    let params = {
      contentType: file.type || "image/png"
    };
    const {
      data: { data }
    } = await uploadParamUpload(params);
    console.log("getUploadParamUpload", data);
    uploadImage(data, file);
  } catch (error) {
    console.log("getUploadParamUpload", error);
  }
};

// 上传图片
const uploadImage = async (xhrData, file) => {
  console.log("uploadImage", xhrData, file);
  try {
    const formData = new FormData();
    for (const key in xhrData.param) {
      const value = xhrData.param[key];
      formData.append(key, value);
    }
    formData.append("file", file);
    // console.log(xhrData.param, formData.get('file'), 9898);
    let config = {
      method: "post",
      // maxBodyLength: Infinity,
      url: xhrData.uploadUrl,
      data: formData,
      headers: {
        "Content-Type": "multipart/form-data"
      }
    };
    const res = await axios.request(config);
    modelValue.value = xhrData.accessUrl;
    console.log("uploadImage", res);
  } catch (error) {
    modelValue.value = "";
    uploadRef.value.clearFiles();
    console.log("uploadImage", error);
  }
};
</script>

<style scoped lang="scss">
.imglist {
  width: 148px;
  height: 148px;
  border-radius: 6px;
  overflow: hidden;
  position: relative;
  border: 1px solid var(--el-border-color);
  .imglist-img {
    width: 100%;
    height: 100%;
  }
  .imglist-actions {
    align-items: center;
    background-color: var(--el-overlay-color-lighter);
    color: #fff;
    cursor: default;
    display: inline-flex;
    font-size: 20px;
    height: 100%;
    justify-content: center;
    left: 0;
    opacity: 0;
    position: absolute;
    top: 0;
    transition: opacity var(--el-transition-duration);
    width: 100%;
    span {
      display: inline-flex;
      cursor: pointer;
    }
    &:hover {
      opacity: 1;
    }
    .imglist-delete {
    }
  }
}

.hide {
  :deep(.el-upload--picture-card) {
    display: none;
  }
}
</style>

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要实现二次封装el-upload回显多个图片,你可以按照以下步骤进行: 1. 在el-upload组件的基础上封装一个新组件,并命名为MultiUpload。 2. 在MultiUpload组件中,添加一个data属性,用于存储已上的图片路径数组。 3. 在el-upload组件中,添加一个success事件处理函数。在该函数中,将上成功的图片路径添加到data属性中保存。 4. 在MultiUpload组件中,添加一个template模板。该模板中,可以使用v-for指令遍历data属性中的图片路径数组,并将每个图片路径渲染到页面上。 下面是一个简单的MultiUpload组件示例代码: ``` <template> <el-upload action="/upload" :on-success="handleSuccess" multiple :show-file-list="false"> <el-button type="primary">点击上</el-button> </el-upload> <div v-for="url in imageUrlList" :key="url"> <img :src="url" alt="uploaded image" style="max-width: 100%;"> </div> </template> <script> export default { data() { return { imageUrlList: [] } }, methods: { handleSuccess(response, file, fileList) { this.imageUrlList.push(response.url) } } } </script> ``` 在这个示例代码中,MultiUpload组件使用了element-ui中的el-upload组件,并通过v-for指令遍历了imageUrlList数组中的图片路径,并将每个图片路径渲染到页面上。在handleSuccess方法中,将上成功的图片路径添加到imageUrlList数组中保存。 使用这个二次封装的MultiUpload组件时,只需要像使用el-upload组件一样使用即可。例如: ``` <multi-upload></multi-upload> ``` 这里没有递任何属性或事件处理函数,因为MultiUpload组件中已经处理了所有必要的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JackieDYH

谢谢您嘞!我会继续加油地

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值