關(guān)于ElementUI的el-upload組件二次封裝的問題
更新時間:2022年10月08日 15:26:53 作者:前端發(fā)現(xiàn)
這篇文章主要介紹了關(guān)于ElementUI的el-upload組件二次封裝的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
ElementUI的el-upload組件二次封裝問題
開發(fā)工作中我們都會遇到圖片上傳的問題,雖說ElementUI已有提供圖片上傳的組件,但我們用到圖片上傳的地方肯定不止一處的,并且框架自帶的組件并不能完全滿足我們的需求,為此我對原有組件做了二次封裝,做到一次封裝,到處使用!
直接上代碼:
組件
**uploadImg.vue** <template> ? <div> ? ? <el-upload :disabled="idCardIsUpload" class="avatar-uploader" action="" list-type="picture" :show-file-list="false" :http-request="diyRequest"> ? ? ? <el-image v-if="idCardImgUrl" :src="idCardImgUrl" name="idCardImgUrl" class="avatar" @error="imgLoadError"></el-image> ? ? ? <el-progress style="margin: 5px;" :width='70' v-else-if="idCardIsUpload" type="circle" :percentage="idCardUploadPercentage"></el-progress> ? ? ? <div v-else class="div-plus"> ? ? ? ? <i class="el-icon-plus avatar-uploader-icon"></i> ? ? ? </div> ? ? </el-upload> ? </div> </template> <script> export default { ? data() { ? ? return { ? ? ? idCardImgUrl: '', ? ? ? idCardIsUpload: false, ? ? ? idCardUploadPercentage: 0, ? ? ? errorImgUrls: [], ? ? } ? }, ? props: { ? ?? ?/*可以在使用組件的時候傳入一個支持上傳的圖片格式的數(shù)組進來,不傳默認default數(shù)組*/ ? ? supportType: {//支持上傳文件的格式 ? ? ? default: () => ['image/jpeg', 'image/jpg', 'image/png'], ? ? ? type: Array ? ? } ? }, ? methods: { ? ?? ?/*父組件執(zhí)行的方法*/ ? ? setEditImg(path) { ? ? ? this.idCardImgUrl = path ? path : '' ? ? }, ? ? /*自定義上傳的方法*/ ? ? diyRequest(param) { ? ? ? /*對上傳圖片的大小和格式校驗*/ ? ? ? const isLt10M = param.file.size / 1024 / 1024 < 4 ? ? ? if (this.supportType.indexOf(param.file.type) == -1) { ? ? ? ? let supportType = this.supportType ? ? ? ? let msg = '' ? ? ? ? supportType.map(res => { ? ? ? ? ? msg += res.substring(6) + '/' ? ? ? ? }) ? ? ? ? let newMsg = msg.slice(0, (msg.length) - 1) ? ? ? ? this.$Message('error', `請上傳正確的圖片格式!支持的格式有:` + newMsg) ? ? ? ? return ? ? ? } ? ? ? if (!isLt10M) { ? ? ? ? this.$Message('error', '上傳圖片大小不能超過4MB哦!') ? ? ? ? return ? ? ? } ? ? ? const fileObj = param.file ? ? ? const form = new FormData() ? ? ? form.append('file', fileObj) ? ? ? let callback = (progress) => { ? ? ? ? this.idCardIsUpload = true ? ? ? ? this.idCardUploadPercentage = progress ? ? ? } ? ? ? /*走后臺接口,這里自行換成自己的api*/ ? ? ? this.$api.addUploadImg(form, callback).then(res => { ? ? ? ? this.idCardIsUpload = false ? ? ? ? this.idCardUploadPercentage = 0 ? ? ? ? if (res.code == 200) { ? ? ? ? ? this.idCardImgUrl = res.data.basePath + res.data.url ? ? ? ? ? /*成功之后將圖片路徑暴露給父組件去顯示圖片*/ ? ? ? ? ? this.$emit('setCardPic', res.data.url) ? ? ? ? } else { ? ? ? ? ? this.$Message('error', res.message) ? ? ? ? } ? ? ? }) ? ? }, ? ? /*當圖片顯示失敗的時候,我會重復(fù)10次賦值圖片,成功顯示就退出,還是失敗就會顯示失敗*/ ? ? imgLoadError(error) { ? ? ? let isExist = false ? ? ? const src = error.path[0].src.split('?')[0] ? ? ? if (this.errorImgUrls.length == 0) { ? ? ? ? this.errorImgUrls.push({ 'src': src, 'number': 1 }) ? ? ? } ? ? ? for (let i = 0; i < this.errorImgUrls.length; i++) { ? ? ? ? if (src === this.errorImgUrls[i].src) { ? ? ? ? ? isExist = true ? ? ? ? ? while (this.errorImgUrls[i].number < 10) { ? ? ? ? ? ? console.log('我在重復(fù)賦值...') ? ? ? ? ? ? this.errorImgUrls[i].number++ ? ? ? ? ? ? const timestamp1 = Date.parse(new Date()) ? ? ? ? ? ? this[error.path[0].name] = src + '?t=' + timestamp1 ? ? ? ? ? } ? ? ? ? } ? ? ? } ? ? ? if (!isExist) {//首次上傳(不在錯誤數(shù)組圖片中,需要執(zhí)行循環(huán)三次賦值) ? ? ? ? this.errorImgUrls.push({ 'src': src, 'number': 1 }) ? ? ? ? this.imgLoadError(error) ? ? ? } ? ? }, ? } } </script>
<style lang="scss" scoped> .div-plus { ? width: 174px; ? height: 174px; ? display: flex; ? align-items: center; ? justify-content: center; } </style> <style lang="scss"> .avatar-uploader .el-upload { ? border: 1px dashed #d9d9d9; ? border-radius: 6px; ? cursor: pointer; ? position: relative; ? overflow: hidden; } .avatar-uploader .el-upload:hover { ? border-color: #409eff; } .avatar-uploader-icon { ? font-size: 28px; ? color: #8c939d; ? width: 120px; ? text-align: center; } .avatar { ? width: 120px; ? height: 120px; ? display: block; } </style>
使用
/*導(dǎo)入組件*/ import uploadImg from '@/components/uploadImg' /*組件注冊*/ export default { ?? ?components: { uploadImg }, ?? ?data(){ ?? ??? ?imgpath: '', ?? ?}, ?? ?methods:{ ?? ??? ?/*執(zhí)行uploadImg組件報出來的事件,path就是顯示圖片的路徑*/ ?? ??? ?setCardPic(path, pic) { ?? ? ? ? ?this.form[pic] = path ?? ? ? ?}, ?? ? ? ?/*詳情的時候設(shè)定顯示圖片的路徑 setEditImg是uploadImg組件提供的方法 imgpath是子組件的ref屬性(看使用的組件)*/ ?? ? ? ?this.$refs.imgpath.setEditImg('') ?? ?} } <template> <el-form-item label="廣告圖片:" prop="imgpath"> ??? ?<uploadImg @setCardPic="setCardPic($event,'imgpath')" ref="imgpath"></uploadImg> ? ?? ?<span style="font-size: 12px;color: #606266;">只能上傳jpg/png/jpeg文件,且不超過4MB</span> </el-form-item> </template>
效果:
el-upload組件封裝后更好用了
對el-upload進行了簡單的二次封裝,實現(xiàn)了圖片上傳后回顯的預(yù)覽大圖和移除圖片。
組件截圖
圖片上傳
圖片的回顯和操作
組件代碼部分
<template> ? <div class="component-upload-image"> ? ? <el-upload ? ? ? :action="uploadImgUrl" ? ? ? list-type="picture-card" ? ? ? :on-success="handleUploadSuccess" ? ? ? :before-upload="handleBeforeUpload" ? ? ? :on-error="handleUploadError" ? ? ? name="file" ? ? ? :show-file-list="false" ? ? ? :headers="headers" ? ? ? style="display: inline-block; vertical-align: top" ? ? > ? ? ? <el-image v-if="!value" :src="value"> ? ? ? ? <div slot="error" class="image-slot"> ? ? ? ? ? <i class="el-icon-plus" /> ? ? ? ? </div> ? ? ? </el-image> ? ? ? <div v-else class="image"> ? ? ? ? <el-image :src="value" :style="`width:150px;height:150px;`" fit="fill"/> ? ? ? ? <div class="mask"> ? ? ? ? ? <div class="actions"> ? ? ? ? ? ? <span title="預(yù)覽" @click.stop="dialogVisible = true"> ? ? ? ? ? ? ? <i class="el-icon-zoom-in" /> ? ? ? ? ? ? </span> ? ? ? ? ? ? <span title="移除" @click.stop="removeImage"> ? ? ? ? ? ? ? <i class="el-icon-delete" /> ? ? ? ? ? ? </span> ? ? ? ? ? </div> ? ? ? ? </div> ? ? ? </div> ? ? </el-upload> ? ? <el-dialog :visible.sync="dialogVisible" title="預(yù)覽" width="800" append-to-body> ? ? ? <img :src="value" style="display: block; max-width: 100%; margin: 0 auto;"> ? ? </el-dialog> ? </div> </template>
<script> import { getToken } from "@/utils/auth"; export default { ? name:'ImageUpload', ? data() { ? ? return { ? ? ? dialogVisible: false, ? ? ? uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上傳的圖片服務(wù)器地址 ? ? ? headers: { ? ? ? ? Authorization: "Bearer " + getToken(), ? ? ? }, ? ? }; ? }, ? props: { ? ? value: { ? ? ? type: String, ? ? ? default: "", ? ? }, ? }, ? methods: { ? ? removeImage() { ? ? ? this.$emit("input", ""); ? ? }, ? ? handleUploadSuccess(res) { ? ? ? this.$emit("input", res.url); ? ? ? this.loading.close(); ? ? }, ? ? handleBeforeUpload() { ? ? ? this.loading = this.$loading({ ? ? ? ? lock: true, ? ? ? ? text: "上傳中", ? ? ? ? spinner: 'el-icon-loading', ? ? ? ? background: "rgba(0, 0, 0, 0.5)", ? ? ? ? customClass:'customClass' ? ? ? }); ? ? }, ? ? handleUploadError() { ? ? ? this.$message({ ? ? ? ? type: "error", ? ? ? ? message: "上傳失敗", ? ? ? }); ? ? ? this.loading.close(); ? ? }, ? }, ? watch: {}, }; </script>
<style scoped lang="scss"> .image { ? position: relative; ? .mask { ? ? opacity: 0; ? ? position: absolute; ? ? top: 0; ? ? width: 100%; ? ? background-color: rgba(0, 0, 0, 0.5); ? ? transition: all 0.3s; ? } ? &:hover .mask { ? ? opacity: 1; ? } } </style>
引入組件試試吧~
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
element的el-table自定義最后一行的實現(xiàn)代碼
最后一行要顯示一些其他結(jié)果,用的是element? ui 自帶的數(shù)據(jù)總計的屬性;返回一個數(shù)組,會按下標進行展示,這篇文章主要介紹了element的el-table自定義最后一行的實現(xiàn)代碼,需要的朋友可以參考下2024-03-03Vue+FormData+axios實現(xiàn)圖片上傳功能的項目實戰(zhàn)
本文主要介紹了Vue+FormData+axios實現(xiàn)圖片上傳功能的項目實戰(zhàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06關(guān)于SpringBoot與Vue交互跨域問題解決方案
最近在利用springboot+vue整合開發(fā)一個前后端分離的個人博客網(wǎng)站,所以這一篇總結(jié)一下在開發(fā)中遇到的一個問題,關(guān)于解決在使用vue和springboot在開發(fā)前后端分離的項目時,如何解決跨域問題。在這里分別分享兩種方法,分別在前端vue中解決和在后臺springboot中解決。2021-10-10