1.VUE2圖片上傳封裝
使用
<ImageUpload v-model="picUrl" :fileSize="0" @getImg="getImg"></ImageUpload>
封裝代碼
<template><div class="component-upload-image"><el-uploadmultiple:action="uploadImgUrl"list-type="picture-card":on-success="handleUploadSuccess":before-upload="handleBeforeUpload":limit="limit":on-error="handleUploadError":on-exceed="handleExceed"ref="imageUpload":on-remove="handleDelete":show-file-list="true":headers="headers":file-list="fileList":on-preview="handlePictureCardPreview":class="{hide: this.fileList.length >= this.limit}"><i class="el-icon-plus"></i></el-upload><!-- 上傳提示 --><div class="el-upload__tip" slot="tip" v-if="showTip">請上傳<template v-if="fileSize"> 大小不超過 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template><template v-if="fileType"> 格式為 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>的文件</div><el-dialog:visible.sync="dialogVisible"title="預覽"width="800"append-to-body><img:src="dialogImageUrl"style="display: block; max-width: 100%; margin: 0 auto"/></el-dialog></div>
</template><script>
import { getToken } from "@/utils/auth";
import { listByIds, delOss } from "@/api/system/oss";export default {props: {value: [String, Object, Array],// 圖片數量限制limit: {type: Number,default: 5,},// 大小限制(MB)fileSize: {type: Number,default: 5,},// 文件類型, 例如['png', 'jpg', 'jpeg']fileType: {type: Array,default: () => ["png", "jpg", "jpeg"],},// 是否顯示提示isShowTip: {type: Boolean,default: true}},data() {return {number: 0,uploadList: [],dialogImageUrl: "",dialogVisible: false,hideUpload: false,baseUrl: process.env.VUE_APP_BASE_API,uploadImgUrl: process.env.VUE_APP_BASE_API + "/system/oss/upload", // 上傳的圖片服務器地址headers: {Authorization: "Bearer " + getToken(),},fileList: []};},watch: {value: {async handler(val) {if (val) {// 首先將值轉為數組let list;if (Array.isArray(val)) {list = val;} else {await listByIds(val).then(res => {list = res.data;this.$emit("getImg", list);})}// 然后將數組轉為對象數組this.fileList = list.map(item => {// 此處name使用ossId 防止刪除出現重名item = { name: item.ossId, url: item.url, ossId: item.ossId };return item;});} else {this.fileList = [];return [];}},deep: true,immediate: true}},computed: {// 是否顯示提示showTip() {return this.isShowTip && (this.fileType || this.fileSize);},},methods: {// 上傳前loading加載handleBeforeUpload(file) {let isImg = false;if (this.fileType.length) {let fileExtension = "";if (file.name.lastIndexOf(".") > -1) {fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);}isImg = this.fileType.some((type) => {if (file.type.indexOf(type) > -1) return true;if (fileExtension && fileExtension.indexOf(type) > -1) return true;return false;});} else {isImg = file.type.indexOf("image") > -1;}if (!isImg) {this.$modal.msgError(`文件格式不正確, 請上傳${this.fileType.join("/")}圖片格式文件!`);return false;}if (this.fileSize) {const isLt = file.size / 1024 / 1024 < this.fileSize;if (!isLt) {this.$modal.msgError(`上傳頭像圖片大小不能超過 ${this.fileSize} MB!`);return false;}}this.$modal.loading("正在上傳圖片,請稍候...");this.number++;},// 文件個數超出handleExceed() {this.$modal.msgError(`上傳文件數量不能超過 ${this.limit} 個!`);},// 上傳成功回調handleUploadSuccess(res, file) {if (res.code === 200) {this.uploadList.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId });this.uploadedSuccessfully();} else {this.number--;this.$modal.closeLoading();this.$modal.msgError(res.msg);this.$refs.imageUpload.handleRemove(file);this.uploadedSuccessfully();}},// 刪除圖片handleDelete(file) {const findex = this.fileList.map(f => f.name).indexOf(file.name);if(findex > -1) {let ossId = this.fileList[findex].ossId;// delOss(ossId);this.fileList.splice(findex, 1);this.$emit("input", this.listToString(this.fileList));}},// 上傳失敗handleUploadError(res) {this.$modal.msgError("上傳圖片失敗,請重試");this.$modal.closeLoading();},// 上傳結束處理uploadedSuccessfully() {if (this.number > 0 && this.uploadList.length === this.number) {this.fileList = this.fileList.concat(this.uploadList);this.uploadList = [];this.number = 0;this.$emit("input", this.listToString(this.fileList));this.$modal.closeLoading();}},// 預覽handlePictureCardPreview(file) {this.dialogImageUrl = file.url;this.dialogVisible = true;},// 對象轉成指定字符串分隔listToString(list, separator) {let strs = "";separator = separator || ",";for (let i in list) {if (list[i].ossId) {strs += list[i].ossId + separator;}}return strs != "" ? strs.substr(0, strs.length - 1) : "";}}
};
</script>
<style scoped lang="scss">
// .el-upload--picture-card 控制加號部分
::v-deep.hide .el-upload--picture-card {display: none;
}
// 去掉動畫效果
::v-deep .el-list-enter-active,
::v-deep .el-list-leave-active {transition: all 0s;
}::v-deep .el-list-enter, .el-list-leave-active {opacity: 0;transform: translateY(0);
}
</style>
2.文件上傳封裝
使用
<FileUpload v-model="fileIds" :fileSize="0" @getfile="getfile"></FileUpload>
封裝代碼
<template><div class="upload-file"><el-uploadv-if="isUpload"multiple:action="uploadFileUrl":before-upload="handleBeforeUpload":file-list="fileList":limit="limit":on-error="handleUploadError":on-exceed="handleExceed":on-success="handleUploadSuccess":show-file-list="false":headers="headers"class="upload-file-uploader"ref="fileUpload"><!-- 上傳按鈕 --><el-button size="mini" type="primary">選取文件</el-button><!-- 上傳提示 --><div class="el-upload__tip" slot="tip" v-if="showTip">請上傳<template v-if="fileSize">大小不超過 <b style="color: #f56c6c">{{ fileSize }}MB</b></template><template v-if="fileType">格式為 <b style="color: #f56c6c">{{ fileType.join("/") }}</b></template>的文件</div></el-upload><!-- 文件列表 --><transition-groupclass="upload-file-list el-upload-list el-upload-list--text"name="el-fade-in-linear"tag="ul"v-if="isFileList"><li:key="file.url"class="el-upload-list__item ele-upload-list__item-content"style="padding: 0 4px"v-for="(file, index) in fileList"><el-link :href="`${file.url}`" :underline="false" target="_blank"><span class="el-icon-document"> {{ getFileName(file.name) }} </span></el-link><div class="ele-upload-list__item-content-action" v-if="isUpload"><el-link :underline="false" @click="handleDelete(index)" type="danger">刪除</el-link></div></li></transition-group></div>
</template><script>
import { getToken } from "@/utils/auth";
import { listByIds, delOss } from "@/api/system/oss";export default {name: "FileUpload",props: {// 值value: [String, Object, Array],// 數量限制limit: {type: Number,default: 5,},// 大小限制(MB)fileSize: {type: Number,default: 5,},// 文件類型, 例如['png', 'jpg', 'jpeg']fileType: {type: Array | Boolean,// default: () => ["doc", "xls", "ppt", "txt", "pdf"],default: () => ["doc", "docx", "xls", "xlsx", "ppt", ".pptx", "pdf"],},// 是否顯示提示isShowTip: {type: Boolean,default: true,},// 是否顯示文件列表isFileList: {type: Boolean,default: true,},dataIndex: {type: Number | String,default: 0,},// 是否可以上傳isUpload: {type: Boolean,default: true,},},data() {return {number: 0,uploadList: [],baseUrl: process.env.VUE_APP_BASE_API,uploadFileUrl: process.env.VUE_APP_BASE_API + "/system/oss/upload", // 上傳文件服務器地址headers: {Authorization: "Bearer " + getToken(),},fileList: [],};},watch: {value: {async handler(val) {if (val) {let temp = 1;// 首先將值轉為數組let list;if (Array.isArray(val)) {list = val;} else {console.log(val);await listByIds(val).then((res) => {list = res.data.map((oss) => {oss = {name: oss.originalName,url: oss.url,ossId: oss.ossId,};return oss;});this.$emit("getfile", list, this.dataIndex);});}// 然后將數組轉為對象數組this.fileList = list.map((item) => {item = { name: item.name, url: item.url, ossId: item.ossId };item.uid = item.uid || new Date().getTime() + temp++;return item;});} else {this.fileList = [];return [];}},deep: true,immediate: true,},},computed: {// 是否顯示提示showTip() {return this.isShowTip && (this.fileType || this.fileSize);},},methods: {// 上傳前校檢格式和大小handleBeforeUpload(file) {// 校檢文件類型if (this.fileType) {const fileName = file.name.split(".");const fileExt = fileName[fileName.length - 1];const isTypeOk = this.fileType.indexOf(fileExt) >= 0;if (!isTypeOk) {this.$modal.msgError(`文件格式不正確, 請上傳${this.fileType.join("/")}格式文件!`);return false;}}// 校檢文件大小if (this.fileSize) {const isLt = file.size / 1024 / 1024 < this.fileSize;if (!isLt) {this.$modal.msgError(`上傳文件大小不能超過 ${this.fileSize} MB!`);return false;}}this.$modal.loading("正在上傳文件,請稍候...");this.number++;return true;},// 文件個數超出handleExceed() {this.$modal.msgError(`上傳文件數量不能超過 ${this.limit} 個!`);},// 上傳失敗handleUploadError(err) {this.$modal.msgError("上傳文件失敗,請重試");this.$modal.closeLoading();},// 上傳成功回調handleUploadSuccess(res, file) {if (res.code === 200) {this.uploadList.push({name: res.data.fileName,url: res.data.url,ossId: res.data.ossId,});this.uploadedSuccessfully();} else {this.number--;this.$modal.closeLoading();this.$modal.msgError(res.msg);this.$refs.fileUpload.handleRemove(file);this.uploadedSuccessfully();}},// 刪除文件handleDelete(index) {let ossId = this.fileList[index].ossId;// delOss(ossId);this.fileList.splice(index, 1);this.$emit("input", this.listToString(this.fileList));},// 上傳結束處理uploadedSuccessfully() {if (this.number > 0 && this.uploadList.length === this.number) {this.fileList = this.fileList.concat(this.uploadList);this.uploadList = [];this.number = 0;this.$emit("input", this.listToString(this.fileList));this.$modal.closeLoading();}},// 獲取文件名稱getFileName(name) {// 如果是url那么取最后的名字 如果不是直接返回if (name.lastIndexOf("/") > -1) {return name.slice(name.lastIndexOf("/") + 1);} else {return name;}},// 對象轉成指定字符串分隔listToString(list, separator) {let strs = "";separator = separator || ",";for (let i in list) {strs += list[i].ossId + separator;}return strs != "" ? strs.substr(0, strs.length - 1) : "";},},
};
</script><style scoped lang="scss">
.upload-file-uploader {margin-bottom: 5px;
}
.upload-file-list .el-upload-list__item {border: 1px solid #e4e7ed;line-height: 2;margin-bottom: 10px;position: relative;
}
.upload-file-list .ele-upload-list__item-content {display: flex;justify-content: space-between;align-items: center;color: inherit;
}
.ele-upload-list__item-content-action .el-link {margin-right: 10px;
}
</style>
3.圖片回顯
使用
<ImagePreview :src="content.picUrl" :width="150" :height="150"></ImagePreview>
封裝代碼
<template><div><el-image v-for="(item,index) in realSrcList" :key="index":src="`${item}`"fit="cover":style="`width:${realWidth};height:${realHeight};`":preview-src-list="realSrcList"><div slot="error" class="image-slot"><i class="el-icon-picture-outline"></i></div></el-image></div></template><script>export default {name: "ImagePreview",props: {src: {type: String,default: ""},width: {type: [Number, String],default: ""},height: {type: [Number, String],default: ""}},computed: {realSrc() {if (!this.src) {return;}let real_src = this.src.split(",")[0];return real_src;},realSrcList() {if (!this.src) {return;}let real_src_list = this.src.split(",");let srcList = [];real_src_list.forEach(item => {return srcList.push(item);});return srcList;},realWidth() {return typeof this.width == "string" ? this.width : `${this.width}px`;},realHeight() {return typeof this.height == "string" ? this.height : `${this.height}px`;}},
};
</script><style lang="scss" scoped>
.el-image {border-radius: 5px;background-color: #ebeef5;box-shadow: 0 0 5px 1px #ccc;::v-deep .el-image__inner {transition: all 0.3s;cursor: pointer;&:hover {transform: scale(1.2);}}::v-deep .image-slot {display: flex;justify-content: center;align-items: center;width: 100%;height: 100%;color: #909399;font-size: 30px;}
}
</style>
4.文件回顯
使用
<FileUpload v-model="content.fileIds" :isShowTip="false" :fileType="false" :isUpload="false"></FileUpload>
5.樹形封裝
使用
<orginTree v-model="form.deptId" @getdep="getdep"></orginTree>
組件封裝代碼
<template><div><a-tree-selectv-model="orgId"style="width: 100%"size="large":dropdown-style="{ maxHeight: '400px', overflow: 'auto', zIndex: 3000 }"placeholder="請選擇"allow-cleartree-default-expand-all:disabled="disabled":tree-data="vorganTreeData":replaceFields="replaceFields"@change="onChange"></a-tree-select></div>
</template><script>
//注意!!!!!
//在modal彈窗組件中使用該組件需要在關閉彈窗方法里清空數據否則會報錯
import { userdepList } from "@/api/user/user";
export default {name: "vorganTree",props: {value: {// 如果希望value可以接收int類型的值而不報錯,可以將type類型修改為可以兼容字符串和整數的類型type: [String, Number],default: "",},disabled: {type: Boolean,default: false,},replaceFields: {type: Object,default: () => {return {children: "children",title: "label",key: "id",value: "id",};},},},data() {return {orgId: this.value,vorganTreeData: [],deptId: "",};},watch: {value: {handler(newVal) {this.orgId = newVal;},immediate: true,},},mounted() {// this.$bus.$on("id", (data) => {// console.log("我是任務組件,收到了數據", data);// this.deptId = data;// });this.deptId = this.$bus.id;this.userdepList();},methods: {userdepList() {userdepList({ ancestors: this.deptId }).then((res) => {console.log("res.data", res);this.vorganTreeData = res.data;});},selectClear() {this.orgId = undefined;},onChange(value, item, xx) {console.log(11111, value, item, xx);// this.$emit("update:value", value);this.$emit("getdep", value);},},
};
</script><style scoped lang="less">
</style>