国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

vue3+ts - element-plus封裝上傳文件圖片組件

這篇具有很好參考價(jià)值的文章主要介紹了vue3+ts - element-plus封裝上傳文件圖片組件。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

??近期做到的項(xiàng)目中有涉及到上傳圖片上傳文件的需求,因?yàn)槭莗c管理后臺(tái),用到了element-plus框架,所以我也一起使用element-plus中的上傳圖片上傳圖片功能,并對(duì)它進(jìn)行封裝成一個(gè)組件,方便在多個(gè)地方使用。

一、效果圖

1、上傳文件、視頻

elementplus上傳圖片,vue,vue.js,前端,typescript

2、上傳圖片

elementplus上傳圖片,vue,vue.js,前端,typescript

二、代碼分析及全部代碼

??在這里上傳圖片和文件是分成了兩個(gè)組件進(jìn)行封裝的,因?yàn)轫?xiàng)目需求要求不一致,所以分開(kāi)了,大家使用時(shí)有需要的話可以將它們合并到一起。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-523676.html

1、上傳文件相關(guān)代碼
<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 }};文件大小不能超過(guò){{ 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"]);
interface Props {
  acceptType?: string; // 上傳文件類(lèi)型
  acceptTypeDesc?: string; // 描述 - 上傳文件類(lèi)型
  isMultiple?: boolean; //   是否可批量上傳
  limitNum?: number; // 允許上傳文件的最大數(shù)量
  isDisableUpload?: boolean; // 是否禁用上傳
  maxFileSize?: number; // 文件大小
  action?: string;
  fileList?: any; // 回顯的文件
  isDownLoad?: boolean; // 是否可以下載
}
// 接收父組件傳遞過(guò)來(lái)的參數(shù)
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 這里監(jiān)聽(tīng)上傳文件的變化是一個(gè)一個(gè)接收到變化的,所以文件也是一個(gè)一個(gè)上傳到服務(wù)器上面的
const handleChange = async (file: any, fileList: any[]) => {
  // 防止多次執(zhí)行change
  const rawFile = file.raw;
  const list = props.acceptTypeDesc.split("/");
  let acceptTypeList = list.map((its:string)=>{
    return getType(its)
  })
  // 如果要檢索的字符串值沒(méi)有出現(xiàn),則該方法返回 -1
  const ars = acceptTypeList.filter((q:string)=>{
    return rawFile.type.indexOf(q)>-1
  })
  // 用于校驗(yàn)是否符合上傳條件
  const type = props.acceptTypeDesc.replace("/", ", ");
  if (ars.length<1) {
    ElMessage.error(`僅支持格式為${type}的圖片`);
    return false;
  } else if (rawFile.size / 1024 / 1024 > props.maxFileSize) {
    ElMessage.error(`文件大小不能超過(guò)${props.maxFileSize}MB!`);
    const arr = [...waitFileList.value];
    waitFileList.value = arr.filter((item: any) => {
      return item.uid != rawFile.uid;
    });
    return false;
  } else {
    let formData = new FormData();
    formData.append("file", rawFile);
    formData.append("fileType", "2");
    const loadingInstance = ElLoading.service({
      text: "正在上傳",
      background: "rgba(0,0,0,.2)",
    });
    // 上傳到服務(wù)器上面
    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(`文件上傳失敗`);
      });
  }
  return true;
};

// 校驗(yàn)上傳文件格式
const getType = (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
};

// 移除文件
const removeFile = (file: any) => {
  const arr: any[] = [...waitFileList.value];
  waitFileList.value = arr.filter((its: any) => {
    return its.id != file.id;
  });
  emits("fileRemove", waitFileList.value);
};

const handleDownLoad = (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、上傳圖片相關(guān)代碼及分析
<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";
interface Props {
  imageUrl?: string; // 回顯圖片地址
  action?: string; //   上傳地址
  imgText?: string; //   文字可以不傳
  imgUpText?: string; // 上傳按鈕的文字
  disabledType?: boolean; // 是否禁用上傳
}
const props = withDefaults(defineProps<Props>(), {
  imageUrl: "",
  action: "/activity/resource/uploadFile",
  imgText: "支持jpg/jpeg/png;文件大小不能超過(guò)2M;封面圖建議尺寸940px*400px",
  imgUpText: "上傳封面",
  disabledType: false,
});

const imagesURL = ref<string>(props.imageUrl);
const emits = defineEmits(["imgSuccess"]);
const handleChange = (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的圖片");
    return false;
  } else if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error("圖片文件大小不能超過(guò)2MB!");
    return false;
  } else {
    let formData = new FormData();
    formData.append("file", rawFile);
    formData.append("fileType", "1");
    const loadingInstance = ElLoading.service({
      text: "正在上傳",
      background: "rgba(0,0,0,.2)",
    });
    // 請(qǐng)求接口上傳圖片到服務(wù)器
    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(`文件上傳失敗`);
      });
  }
  return true;
};
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>

到了這里,關(guān)于vue3+ts - element-plus封裝上傳文件圖片組件的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Vue3 封裝 element-plus 圖標(biāo)選擇器

    Vue3 封裝 element-plus 圖標(biāo)選擇器

    效果一: 效果二: ? 效果一的這個(gè)是把全部的icon圖標(biāo)都讓它顯示出來(lái),讓我們自己選擇說(shuō)選圖標(biāo) 2.1. 全局注冊(cè) icon 組件 2.2. 組件實(shí)現(xiàn)? 2.3. 使用? 效果二的這個(gè)是渲染后端返回的icon圖標(biāo) 3.1. 全局注冊(cè) icon 組件 3.2. 組件實(shí)現(xiàn)? 3.3. 使用?

    2024年02月07日
    瀏覽(240)
  • vue3-ts- element-plus新增組件-過(guò)濾

    vue3-ts- element-plus新增組件-過(guò)濾

    ?新增組件-所有值為空時(shí)過(guò)濾 ? 提交:?

    2024年02月11日
    瀏覽(23)
  • 使用 Vite + Vue3 + Element-Plus + Pinia + Ts 搭建 Vue3 項(xiàng)目

    使用 Vite + Vue3 + Element-Plus + Pinia + Ts 搭建 Vue3 項(xiàng)目

    Vite 需要 Node.js 版本 14.18+,16+。然而,有些模板需要依賴(lài)更高的 Node 版本才能正常運(yùn)行,當(dāng)你的包管理器發(fā)出警告時(shí),請(qǐng)注意升級(jí)你的 Node 版本。 首先 npm 輸入: Project name :項(xiàng)目名稱(chēng) Select a framework :選擇一個(gè)框架 Select a variant :選擇 ts 或者 js 輸入項(xiàng)目名稱(chēng)后選擇 vue 選擇

    2024年02月09日
    瀏覽(27)
  • vue3 - element-plus 上傳各種 word pdf 文件、圖片視頻并上傳到服務(wù)器功能效果,示例代碼開(kāi)箱即用。

    vue3 - element-plus 上傳各種 word pdf 文件、圖片視頻并上傳到服務(wù)器功能效果,示例代碼開(kāi)箱即用。

    在 vue3 項(xiàng)目中,使用 element plus 組件庫(kù)的 el-upload 上傳組件,進(jìn)行文件、圖片圖像的上傳功能示例。 可直接復(fù)制,再改個(gè)接口地址。 在這里上傳

    2024年02月15日
    瀏覽(52)
  • Vue3+TS+Vite創(chuàng)建項(xiàng)目,并導(dǎo)入Element-plus和Sass

    Vue3+TS+Vite創(chuàng)建項(xiàng)目,并導(dǎo)入Element-plus和Sass

    1.桌面新建一個(gè)文件夾Vue3-app 打開(kāi)編輯器導(dǎo)入文件夾,編輯器打開(kāi)終端輸入或者命令行工具cd到項(xiàng)目目錄下輸入 npm init vue@latest 回車(chē)運(yùn)行 這里我選擇了TS+Vite來(lái)開(kāi)發(fā),并選擇安裝路由 2.cd到 vue-project目錄下 輸入 npm install 回車(chē)運(yùn)行 3.安裝完成后 輸入 npm run dev 回車(chē)運(yùn)行 瀏覽器打開(kāi)

    2024年02月16日
    瀏覽(24)
  • 詳解Vite創(chuàng)建Vue3項(xiàng)目+vue-router+ts+vite+element-plus

    詳解Vite創(chuàng)建Vue3項(xiàng)目+vue-router+ts+vite+element-plus

    前言 在之前的文章中寫(xiě)過(guò)“Vue3+TS+ElementPlus的安裝和使用教程【詳細(xì)講解】”,但那篇文章寫(xiě)的是創(chuàng)建vue3的項(xiàng)目沒(méi)有使用到Vite構(gòu)建工具進(jìn)行創(chuàng)建還是使用的常規(guī)webpacket構(gòu)建工具進(jìn)行創(chuàng)建的。提到Vite和webpacket的時(shí)候我們可以簡(jiǎn)單說(shuō)一下。 Vite 和 Webpack 都是現(xiàn)代化的前端構(gòu)建工

    2024年01月18日
    瀏覽(24)
  • 從0開(kāi)始搭建一個(gè)vue3+vite+ts+pinia+element-plus的項(xiàng)目

    從0開(kāi)始搭建一個(gè)vue3+vite+ts+pinia+element-plus的項(xiàng)目

    前言:vue3+ts+vite大家已經(jīng)都開(kāi)始用了,最近也在學(xué)習(xí),基本上是零基礎(chǔ)開(kāi)始ts的學(xué)習(xí),很多語(yǔ)法知識(shí)是邊寫(xiě)邊查,沒(méi)有系統(tǒng)的學(xué)習(xí)ts。此處展示從零開(kāi)始,搭建的一個(gè)框架,方便拿來(lái)即用! 其中框架選擇vue,語(yǔ)言選擇typeScript 項(xiàng)目啟動(dòng)成功以后如下所示: 為了方便日常工作中

    2024年02月06日
    瀏覽(28)
  • vue3+ts+element-plus實(shí)際開(kāi)發(fā)之導(dǎo)出表格和不同類(lèi)型之間相互賦值

    vue3+ts+element-plus實(shí)際開(kāi)發(fā)之導(dǎo)出表格和不同類(lèi)型之間相互賦值

    1. 安裝依賴(lài) npm run xlsx 2. 引入,import * as XLSX from “xlsx”; 3. 報(bào)錯(cuò)找不到模塊“xlsx”或其相應(yīng)的類(lèi)型聲明 修改成大寫(xiě)就好了 import * as XLSX from \\\'XLSX\\\' ,如果沒(méi)有報(bào)提示就直接用 4. 使用導(dǎo)出文件 //---- 導(dǎo)出表 1. 直接用a標(biāo)簽下載 鼠標(biāo)移入樣式,點(diǎn)擊自動(dòng)下載 2. 有特殊數(shù)據(jù)需要解析

    2024年02月15日
    瀏覽(29)
  • vue3 element-plus el-form的二次封裝

    form表單的二次封裝 vue3 element-plus el-form的二次封裝 屬性名 類(lèi)型 默認(rèn)值 說(shuō)明 data Array [] 頁(yè)面展示數(shù)據(jù)內(nèi)容 onChange Function false 表單事件 bindProps Object {} 表單屬性 formRef Object {} 表單ref ruleForm Object {} 數(shù)據(jù)

    2024年02月13日
    瀏覽(103)
  • vue3+ts+element-plus 之使用node.js對(duì)接mysql進(jìn)行表格數(shù)據(jù)展示

    vue3+ts+element-plus 之使用node.js對(duì)接mysql進(jìn)行表格數(shù)據(jù)展示

    * 初始化node 查看node是否安裝 node -v 初始化命令 npm init 初始化配置解釋如下: 完成后會(huì)有一個(gè)package.json文件 * 安裝可能用到的依賴(lài) 根據(jù)需求安裝,我這里需要對(duì)接mysql,安裝依賴(lài) ,我是一次性安裝完,后邊會(huì)直接使用,也可以邊安裝邊使用。如下 安裝成功如下: * 配置文件

    2024年02月15日
    瀏覽(54)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包