0


vue3+ts - element-plus封装上传文件图片组件

  近期做到的项目中有涉及到上传图片上传文件的需求,因为是pc管理后台,用到了element-plus框架,所以我也一起使用element-plus中的上传图片上传图片功能,并对它进行封装成一个组件,方便在多个地方使用。

一、效果图

1、上传文件、视频

在这里插入图片描述

2、上传图片

在这里插入图片描述

二、代码分析及全部代码

  在这里上传图片和文件是分成了两个组件进行封装的,因为项目需求要求不一致,所以分开了,大家使用时有需要的话可以将它们合并到一起。

1、上传文件相关代码

<template><div class="upload_wrap"><el-upload
      v-if="!props.isDisableUpload"class="upload"
      ref="uploadRef":file-list="waitFileList":multiple="props.isMultiple":limit="props.limitNum":accept="props.acceptType":auto-upload="false":show-file-list="false":disabled="props.isDisableUpload":on-change="handleChange"><div class="el-upload__text"><img src="@/assets/images/icon_upload.png"/><span>上传文件</span></div></el-upload><div class="template_list"><div class="template" v-for="(item, index) in waitFileList":key="index"><span><img src="@/assets/images/icon_link.png"/></span><span class="documentName">{{ item.name }}</span><span v-if="!props.isDisableUpload"><el-icon color="#000000a6" size="16"@click="removeFile(item)"><Close
          /></el-icon></span><span v-if="isDownLoad" style="paddingleft: 5px"><img
            src="@/assets/images/icon_download.png"@click="handleDownLoad(item)"/></span></div></div><span class="tips" v-if="!props.isDisableUpload">支持{{ acceptTypeDesc }};文件大小不能超过{{ props.maxFileSize }}M</span
    ></div></template><script lang="ts" setup>import{ ref, watch }from"vue";import{ ElLoading, ElMessage }from"element-plus";import{ request }from"@/api/axios";import{ Close }from"@element-plus/icons-vue";const emits =defineEmits(["fileSuccess","fileRemove"]);interfaceProps{
  acceptType?:string;// 上传文件类型
  acceptTypeDesc?:string;// 描述 - 上传文件类型
  isMultiple?:boolean;//   是否可批量上传
  limitNum?:number;// 允许上传文件的最大数量
  isDisableUpload?:boolean;// 是否禁用上传
  maxFileSize?:number;// 文件大小
  action?:string;
  fileList?:any;// 回显的文件
  isDownLoad?:boolean;// 是否可以下载}// 接收父组件传递过来的参数const props =withDefaults(defineProps<Props>(),{
  acceptType:".xls,.doc",
  acceptTypeDesc:"doc/xls",
  isMultiple:true,
  limitNum:10,
  isDisableUpload:false,
  maxFileSize:10,
  action:"/activity/resource/uploadFile",
  fileList:[],
  isDownLoad:false,});let waitFileList =ref<any[]>([]);

waitFileList.value = props.fileList;
waitFileList.value?.forEach((item:any)=>{
  item.name = item.original;});watch(()=> props.fileList,()=>{console.log("props.fileList====>", props.fileList);
    waitFileList.value = props.fileList;
    waitFileList.value?.forEach((item:any)=>{
      item.name = item.original;});});// 文件变化Handle 这里监听上传文件的变化是一个一个接收到变化的,所以文件也是一个一个上传到服务器上面的consthandleChange=async(file:any, fileList:any[])=>{// 防止多次执行changeconst rawFile = file.raw;const list = props.acceptTypeDesc.split("/");let acceptTypeList = list.map((its:string)=>{returngetType(its)})// 如果要检索的字符串值没有出现,则该方法返回 -1const ars = acceptTypeList.filter((q:string)=>{return rawFile.type.indexOf(q)>-1})// 用于校验是否符合上传条件const type = props.acceptTypeDesc.replace("/",", ");if(ars.length<1){
    ElMessage.error(`仅支持格式为${type}的图片`);returnfalse;}elseif(rawFile.size /1024/1024> props.maxFileSize){
    ElMessage.error(`文件大小不能超过${props.maxFileSize}MB!`);const arr =[...waitFileList.value];
    waitFileList.value = arr.filter((item:any)=>{return item.uid != rawFile.uid;});returnfalse;}else{let formData =newFormData();
    formData.append("file", rawFile);
    formData.append("fileType","2");const loadingInstance = ElLoading.service({
      text:"正在上传",
      background:"rgba(0,0,0,.2)",});// 上传到服务器上面const requestURL:string= props.action;request("post", requestURL, formData,{
      headers:{"Content-Type":"multipart/form-data"},}).then(async(res:any)=>{if(res.code ==0){
          loadingInstance.close();let obj ={...res.data,
            name: res.data.original,};emits("fileSuccess", obj);}else{
          loadingInstance.close();
          ElMessage.warning(`文件上传失败`);}}).catch(()=>{
        loadingInstance.close();// ElMessage.warning(`文件上传失败`);});}returntrue;};// 校验上传文件格式constgetType=(acceptType:string)=>{let val ="";switch(acceptType){case"xls":
      val ="excel";break;case"doc":
      val ="word";break;case"pdf":
      val ="pdf";break;case"zip":
      val ="zip";break;case"xlsx":
      val ="sheet";break;case"pptx":
      val ="presentation";break;case"docx":
      val ="document";break;case"text":
      val ="text";break;}return val
};// 移除文件constremoveFile=(file:any)=>{const arr:any[]=[...waitFileList.value];
  waitFileList.value = arr.filter((its:any)=>{return its.id != file.id;});emits("fileRemove", waitFileList.value);};consthandleDownLoad=(row:{ ossFile:string})=>{const str = window.location.href.split("#")[0];const herf = str.slice(0, str.length -1);
  window.location.href = herf + row.ossFile;};</script><style lang="scss" scoped>.upload_wrap {.upload {
    min-width: 468px;
    padding-bottom: 10px;}.tips {
    display: block;
    font-size: 14px;
    font-family: PingFangSC-Regular, PingFang SC;
    font-weight:400;
    color:rgba(0,0,0,0.65);}}:deep().el-upload__text {
  width: 106px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #ffffff;
  border: 1px solid rgba(0,0,0,0.15);
  img {
    display: block;
    width: 14px;
    height: 14px;}

  span {
    font-size: 14px;
    padding-left: 6px;
    font-family: PingFangSC-Regular, PingFang SC;
    font-weight:400;
    color:rgba(0,0,0,0.65);}}.template_list {
  padding-bottom: 4px;}.template {
  display: flex;
  align-items: center;
  padding: 5px 0;
  span {
    line-height: 16px;}
  img {
    margin-right: 8px;
    width: 16px;
    height: 16px;}.documentName {
    margin-right: 12px;
    font-size: 14px;
    color:rgba(0,0,0,0.65);}}</style>

2、上传图片相关代码及分析

<template><div class="avatar-uploader"><el-upload
      class="avatar-uploader":show-file-list="false":disabled="disabledType":auto-upload="false"
      accept=".png,.jepg,.jpg"
      ref="excelUploadRef":on-change="handleChange"><img
        v-if="imagesURL || props.imageUrl":src="props.imageUrl ? props.imageUrl : imagesURL"class="avatar"/><div class="upImgBox" v-else><el-icon class="avatar-uploader-icon"><Plus /></el-icon><div>{{ imgUpText }}</div></div></el-upload><div class="upImgText">{{ imgText }}</div></div></template><script lang="ts" setup>import{ ref, watch }from"vue";import{ Plus }from"@element-plus/icons-vue";import{ ElMessage, ElLoading }from"element-plus";import{ request }from"@/api/axios";interfaceProps{
  imageUrl?:string;// 回显图片地址
  action?:string;//   上传地址
  imgText?:string;//   文字可以不传
  imgUpText?:string;// 上传按钮的文字
  disabledType?:boolean;// 是否禁用上传}const props =withDefaults(defineProps<Props>(),{
  imageUrl:"",
  action:"/activity/resource/uploadFile",
  imgText:"支持jpg/jpeg/png;文件大小不能超过2M;封面图建议尺寸940px*400px",
  imgUpText:"上传封面",
  disabledType:false,});const imagesURL =ref<string>(props.imageUrl);const emits =defineEmits(["imgSuccess"]);consthandleChange=(file:any, fileList:any)=>{console.log(file);console.log(fileList);let rawFile = file.raw;if(
    rawFile.type !=="image/jpeg"&&
    rawFile.type !=="image/png"&&
    rawFile.type !=="image/jpg"){
    ElMessage.error("仅支持格式为jpg, jpeg, png的图片");returnfalse;}elseif(rawFile.size /1024/1024>2){
    ElMessage.error("图片文件大小不能超过2MB!");returnfalse;}else{let formData =newFormData();
    formData.append("file", rawFile);
    formData.append("fileType","1");const loadingInstance = ElLoading.service({
      text:"正在上传",
      background:"rgba(0,0,0,.2)",});// 请求接口上传图片到服务器let requestURL = props.action;request("post", requestURL, formData,{
      headers:{"Content-Type":"multipart/form-data"},}).then(async(res:any)=>{console.log(res);if(res.code ==0){
          loadingInstance.close();let obj ={
            imgUrl: res.data.ossFile,
            raw: res.data,};emits("imgSuccess", obj);
          imagesURL.value = res.data.ossFile;}else{
          loadingInstance.close();
          ElMessage.warning(`文件上传失败`);}}).catch(()=>{
        loadingInstance.close();
        ElMessage.warning(`文件上传失败`);});}returntrue;};watch(()=> props.imageUrl,()=>{
    imagesURL.value = props.imageUrl;});</script><style lang="scss" scoped>:deep().avatar-uploader {.avatar {
    width: 104px;
    height: 104px;
    display: block;}.el-upload {
    border: 1px dashed #dcdfe6;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition:0.2s;
    background:rgba(0,0,0,0.04)!important;}.el-upload:hover {
    border-color: #14b194;}}.el-icon.avatar-uploader-icon {
  font-size: 16px;
  color:rgba(0,0,0,0.45);
  text-align: center;}.upImgBox {
  width: 104px;
  height: 104px;
  font-size: 14px;
  font-family: PingFangSC-Regular, PingFang SC;
  font-weight:400;
  color:rgba(0,0,0,0.65);
  text-align: center;
  padding-top: 24px;
  box-sizing: border-box;}.upImgText {
  font-size: 14px;
  color:rgba(0,0,0,0.6);
  margin-top: 4px;}</style>

本文转载自: https://blog.csdn.net/LiaoFengJi/article/details/128917787
版权归原作者 紫菀檀ss 所有, 如有侵权,请联系我们删除。

“vue3+ts - element-plus封装上传文件图片组件”的评论:

还没有评论