vue2组件封装+elementUI

打印 上一主题 下一主题

主题 646|帖子 646|积分 1938

1.VUE2图片上传封装

使用

  1.    <ImageUpload v-model="picUrl" :fileSize="0"  @getImg="getImg"></ImageUpload>
复制代码
封装代码

  1. <template>
  2.   <div class="component-upload-image">
  3.     <el-upload
  4.       multiple
  5.       :action="uploadImgUrl"
  6.       list-type="picture-card"
  7.       :on-success="handleUploadSuccess"
  8.       :before-upload="handleBeforeUpload"
  9.       :limit="limit"
  10.       :on-error="handleUploadError"
  11.       :on-exceed="handleExceed"
  12.       ref="imageUpload"
  13.       :on-remove="handleDelete"
  14.       :show-file-list="true"
  15.       :headers="headers"
  16.       :file-list="fileList"
  17.       :on-preview="handlePictureCardPreview"
  18.       :class="{hide: this.fileList.length >= this.limit}"
  19.     >
  20.       <i class="el-icon-plus"></i>
  21.     </el-upload>
  22.     <!-- 上传提示 -->
  23.     <div class="el-upload__tip" slot="tip" v-if="showTip">
  24.       请上传
  25.       <template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
  26.       <template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
  27.       的文件
  28.     </div>
  29.     <el-dialog
  30.       :visible.sync="dialogVisible"
  31.       title="预览"
  32.       width="800"
  33.       append-to-body
  34.     >
  35.       <img
  36.         :src="dialogImageUrl"
  37.         style="display: block; max-width: 100%; margin: 0 auto"
  38.       />
  39.     </el-dialog>
  40.   </div>
  41. </template>
  42. <script>
  43. import { getToken } from "@/utils/auth";
  44. import { listByIds, delOss } from "@/api/system/oss";
  45. export default {
  46.   props: {
  47.     value: [String, Object, Array],
  48.     // 图片数量限制
  49.     limit: {
  50.       type: Number,
  51.       default: 5,
  52.     },
  53.     // 大小限制(MB)
  54.     fileSize: {
  55.        type: Number,
  56.       default: 5,
  57.     },
  58.     // 文件类型, 例如['png', 'jpg', 'jpeg']
  59.     fileType: {
  60.       type: Array,
  61.       default: () => ["png", "jpg", "jpeg"],
  62.     },
  63.     // 是否显示提示
  64.     isShowTip: {
  65.       type: Boolean,
  66.       default: true
  67.     }
  68.   },
  69.   data() {
  70.     return {
  71.       number: 0,
  72.       uploadList: [],
  73.       dialogImageUrl: "",
  74.       dialogVisible: false,
  75.       hideUpload: false,
  76.       baseUrl: process.env.VUE_APP_BASE_API,
  77.       uploadImgUrl: process.env.VUE_APP_BASE_API + "/system/oss/upload", // 上传的图片服务器地址
  78.       headers: {
  79.         Authorization: "Bearer " + getToken(),
  80.       },
  81.       fileList: []
  82.     };
  83.   },
  84.   watch: {
  85.     value: {
  86.       async handler(val) {
  87.         if (val) {
  88.           // 首先将值转为数组
  89.           let list;
  90.           if (Array.isArray(val)) {
  91.             list = val;
  92.           } else {
  93.             await listByIds(val).then(res => {
  94.               list = res.data;
  95.               this.$emit("getImg", list);
  96.             })
  97.           }
  98.           // 然后将数组转为对象数组
  99.           this.fileList = list.map(item => {
  100.             // 此处name使用ossId 防止删除出现重名
  101.             item = { name: item.ossId, url: item.url, ossId: item.ossId };
  102.             return item;
  103.           });
  104.         } else {
  105.           this.fileList = [];
  106.           return [];
  107.         }
  108.       },
  109.       deep: true,
  110.       immediate: true
  111.     }
  112.   },
  113.   computed: {
  114.     // 是否显示提示
  115.     showTip() {
  116.       return this.isShowTip && (this.fileType || this.fileSize);
  117.     },
  118.   },
  119.   methods: {
  120.     // 上传前loading加载
  121.     handleBeforeUpload(file) {
  122.       let isImg = false;
  123.       if (this.fileType.length) {
  124.         let fileExtension = "";
  125.         if (file.name.lastIndexOf(".") > -1) {
  126.           fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
  127.         }
  128.         isImg = this.fileType.some((type) => {
  129.           if (file.type.indexOf(type) > -1) return true;
  130.           if (fileExtension && fileExtension.indexOf(type) > -1) return true;
  131.           return false;
  132.         });
  133.       } else {
  134.         isImg = file.type.indexOf("image") > -1;
  135.       }
  136.       if (!isImg) {
  137.         this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join("/")}图片格式文件!`);
  138.         return false;
  139.       }
  140.       if (this.fileSize) {
  141.         const isLt = file.size / 1024 / 1024 < this.fileSize;
  142.         if (!isLt) {
  143.           this.$modal.msgError(`上传头像图片大小不能超过 ${this.fileSize} MB!`);
  144.           return false;
  145.         }
  146.       }
  147.       this.$modal.loading("正在上传图片,请稍候...");
  148.       this.number++;
  149.     },
  150.     // 文件个数超出
  151.     handleExceed() {
  152.       this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
  153.     },
  154.     // 上传成功回调
  155.     handleUploadSuccess(res, file) {
  156.       if (res.code === 200) {
  157.         this.uploadList.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId });
  158.         this.uploadedSuccessfully();
  159.       } else {
  160.         this.number--;
  161.         this.$modal.closeLoading();
  162.         this.$modal.msgError(res.msg);
  163.         this.$refs.imageUpload.handleRemove(file);
  164.         this.uploadedSuccessfully();
  165.       }
  166.     },
  167.     // 删除图片
  168.     handleDelete(file) {
  169.       const findex = this.fileList.map(f => f.name).indexOf(file.name);
  170.       if(findex > -1) {
  171.         let ossId = this.fileList[findex].ossId;
  172.         // delOss(ossId);
  173.         this.fileList.splice(findex, 1);
  174.         this.$emit("input", this.listToString(this.fileList));
  175.       }
  176.     },
  177.     // 上传失败
  178.     handleUploadError(res) {
  179.       this.$modal.msgError("上传图片失败,请重试");
  180.       this.$modal.closeLoading();
  181.     },
  182.     // 上传结束处理
  183.     uploadedSuccessfully() {
  184.       if (this.number > 0 && this.uploadList.length === this.number) {
  185.         this.fileList = this.fileList.concat(this.uploadList);
  186.         this.uploadList = [];
  187.         this.number = 0;
  188.         this.$emit("input", this.listToString(this.fileList));
  189.         this.$modal.closeLoading();
  190.       }
  191.     },
  192.     // 预览
  193.     handlePictureCardPreview(file) {
  194.       this.dialogImageUrl = file.url;
  195.       this.dialogVisible = true;
  196.     },
  197.     // 对象转成指定字符串分隔
  198.     listToString(list, separator) {
  199.       let strs = "";
  200.       separator = separator || ",";
  201.       for (let i in list) {
  202.         if (list[i].ossId) {
  203.           strs += list[i].ossId + separator;
  204.         }
  205.       }
  206.       return strs != "" ? strs.substr(0, strs.length - 1) : "";
  207.     }
  208.   }
  209. };
  210. </script>
  211. <style scoped lang="scss">
  212. // .el-upload--picture-card 控制加号部分
  213. ::v-deep.hide .el-upload--picture-card {
  214.     display: none;
  215. }
  216. // 去掉动画效果
  217. ::v-deep .el-list-enter-active,
  218. ::v-deep .el-list-leave-active {
  219.     transition: all 0s;
  220. }
  221. ::v-deep .el-list-enter, .el-list-leave-active {
  222.   opacity: 0;
  223.   transform: translateY(0);
  224. }
  225. </style>
复制代码
2.文件上传封装

使用

  1. <FileUpload v-model="fileIds" :fileSize="0"  @getfile="getfile"></FileUpload>
复制代码
封装代码

  1. <template>
  2.   <div class="upload-file">
  3.     <el-upload
  4.       v-if="isUpload"
  5.       multiple
  6.       :action="uploadFileUrl"
  7.       :before-upload="handleBeforeUpload"
  8.       :file-list="fileList"
  9.       :limit="limit"
  10.       :on-error="handleUploadError"
  11.       :on-exceed="handleExceed"
  12.       :on-success="handleUploadSuccess"
  13.       :show-file-list="false"
  14.       :headers="headers"
  15.       class="upload-file-uploader"
  16.       ref="fileUpload"
  17.     >
  18.       <!-- 上传按钮 -->
  19.       <el-button size="mini" type="primary">选取文件</el-button>
  20.       <!-- 上传提示 -->
  21.       <div class="el-upload__tip" slot="tip" v-if="showTip">
  22.         请上传
  23.         <template v-if="fileSize">
  24.           大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
  25.         </template>
  26.         <template v-if="fileType">
  27.           格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b>
  28.         </template>
  29.         的文件
  30.       </div>
  31.     </el-upload>
  32.     <!-- 文件列表 -->
  33.     <transition-group
  34.       class="upload-file-list el-upload-list el-upload-list--text"
  35.       name="el-fade-in-linear"
  36.       tag="ul"
  37.       v-if="isFileList"
  38.     >
  39.       <li
  40.         :key="file.url"
  41.         class="el-upload-list__item ele-upload-list__item-content"
  42.         style="padding: 0 4px"
  43.         v-for="(file, index) in fileList"
  44.       >
  45.         <el-link :href="`${file.url}`" :underline="false" target="_blank">
  46.           <span class="el-icon-document"> {{ getFileName(file.name) }} </span>
  47.         </el-link>
  48.         <div class="ele-upload-list__item-content-action" v-if="isUpload">
  49.           <el-link :underline="false" @click="handleDelete(index)" type="danger"
  50.             >删除</el-link
  51.           >
  52.         </div>
  53.       </li>
  54.     </transition-group>
  55.   </div>
  56. </template>
  57. <script>
  58. import { getToken } from "@/utils/auth";
  59. import { listByIds, delOss } from "@/api/system/oss";
  60. export default {
  61.   name: "FileUpload",
  62.   props: {
  63.     // 值
  64.     value: [String, Object, Array],
  65.     // 数量限制
  66.     limit: {
  67.       type: Number,
  68.       default: 5,
  69.     },
  70.     // 大小限制(MB)
  71.     fileSize: {
  72.       type: Number,
  73.       default: 5,
  74.     },
  75.     // 文件类型, 例如['png', 'jpg', 'jpeg']
  76.     fileType: {
  77.       type: Array | Boolean,
  78.       // default: () => ["doc", "xls", "ppt", "txt", "pdf"],
  79.       default: () => ["doc", "docx", "xls", "xlsx", "ppt", ".pptx", "pdf"],
  80.     },
  81.     // 是否显示提示
  82.     isShowTip: {
  83.       type: Boolean,
  84.       default: true,
  85.     },
  86.     // 是否显示文件列表
  87.     isFileList: {
  88.       type: Boolean,
  89.       default: true,
  90.     },
  91.     dataIndex: {
  92.       type: Number | String,
  93.       default: 0,
  94.     },
  95.     // 是否可以上传
  96.     isUpload: {
  97.       type: Boolean,
  98.       default: true,
  99.     },
  100.   },
  101.   data() {
  102.     return {
  103.       number: 0,
  104.       uploadList: [],
  105.       baseUrl: process.env.VUE_APP_BASE_API,
  106.       uploadFileUrl: process.env.VUE_APP_BASE_API + "/system/oss/upload", // 上传文件服务器地址
  107.       headers: {
  108.         Authorization: "Bearer " + getToken(),
  109.       },
  110.       fileList: [],
  111.     };
  112.   },
  113.   watch: {
  114.     value: {
  115.       async handler(val) {
  116.         if (val) {
  117.           let temp = 1;
  118.           // 首先将值转为数组
  119.           let list;
  120.           if (Array.isArray(val)) {
  121.             list = val;
  122.           } else {
  123.             console.log(val);
  124.             await listByIds(val).then((res) => {
  125.               list = res.data.map((oss) => {
  126.                 oss = {
  127.                   name: oss.originalName,
  128.                   url: oss.url,
  129.                   ossId: oss.ossId,
  130.                 };
  131.                 return oss;
  132.               });
  133.               this.$emit("getfile", list, this.dataIndex);
  134.             });
  135.           }
  136.           // 然后将数组转为对象数组
  137.           this.fileList = list.map((item) => {
  138.             item = { name: item.name, url: item.url, ossId: item.ossId };
  139.             item.uid = item.uid || new Date().getTime() + temp++;
  140.             return item;
  141.           });
  142.         } else {
  143.           this.fileList = [];
  144.           return [];
  145.         }
  146.       },
  147.       deep: true,
  148.       immediate: true,
  149.     },
  150.   },
  151.   computed: {
  152.     // 是否显示提示
  153.     showTip() {
  154.       return this.isShowTip && (this.fileType || this.fileSize);
  155.     },
  156.   },
  157.   methods: {
  158.     // 上传前校检格式和大小
  159.     handleBeforeUpload(file) {
  160.       // 校检文件类型
  161.       if (this.fileType) {
  162.         const fileName = file.name.split(".");
  163.         const fileExt = fileName[fileName.length - 1];
  164.         const isTypeOk = this.fileType.indexOf(fileExt) >= 0;
  165.         if (!isTypeOk) {
  166.           this.$modal.msgError(
  167.             `文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`
  168.           );
  169.           return false;
  170.         }
  171.       }
  172.       // 校检文件大小
  173.       if (this.fileSize) {
  174.         const isLt = file.size / 1024 / 1024 < this.fileSize;
  175.         if (!isLt) {
  176.           this.$modal.msgError(`上传文件大小不能超过 ${this.fileSize} MB!`);
  177.           return false;
  178.         }
  179.       }
  180.       this.$modal.loading("正在上传文件,请稍候...");
  181.       this.number++;
  182.       return true;
  183.     },
  184.     // 文件个数超出
  185.     handleExceed() {
  186.       this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
  187.     },
  188.     // 上传失败
  189.     handleUploadError(err) {
  190.       this.$modal.msgError("上传文件失败,请重试");
  191.       this.$modal.closeLoading();
  192.     },
  193.     // 上传成功回调
  194.     handleUploadSuccess(res, file) {
  195.       if (res.code === 200) {
  196.         this.uploadList.push({
  197.           name: res.data.fileName,
  198.           url: res.data.url,
  199.           ossId: res.data.ossId,
  200.         });
  201.         this.uploadedSuccessfully();
  202.       } else {
  203.         this.number--;
  204.         this.$modal.closeLoading();
  205.         this.$modal.msgError(res.msg);
  206.         this.$refs.fileUpload.handleRemove(file);
  207.         this.uploadedSuccessfully();
  208.       }
  209.     },
  210.     // 删除文件
  211.     handleDelete(index) {
  212.       let ossId = this.fileList[index].ossId;
  213.       // delOss(ossId);
  214.       this.fileList.splice(index, 1);
  215.       this.$emit("input", this.listToString(this.fileList));
  216.     },
  217.     // 上传结束处理
  218.     uploadedSuccessfully() {
  219.       if (this.number > 0 && this.uploadList.length === this.number) {
  220.         this.fileList = this.fileList.concat(this.uploadList);
  221.         this.uploadList = [];
  222.         this.number = 0;
  223.         this.$emit("input", this.listToString(this.fileList));
  224.         this.$modal.closeLoading();
  225.       }
  226.     },
  227.     // 获取文件名称
  228.     getFileName(name) {
  229.       // 如果是url那么取最后的名字 如果不是直接返回
  230.       if (name.lastIndexOf("/") > -1) {
  231.         return name.slice(name.lastIndexOf("/") + 1);
  232.       } else {
  233.         return name;
  234.       }
  235.     },
  236.     // 对象转成指定字符串分隔
  237.     listToString(list, separator) {
  238.       let strs = "";
  239.       separator = separator || ",";
  240.       for (let i in list) {
  241.         strs += list[i].ossId + separator;
  242.       }
  243.       return strs != "" ? strs.substr(0, strs.length - 1) : "";
  244.     },
  245.   },
  246. };
  247. </script>
  248. <style scoped lang="scss">
  249. .upload-file-uploader {
  250.   margin-bottom: 5px;
  251. }
  252. .upload-file-list .el-upload-list__item {
  253.   border: 1px solid #e4e7ed;
  254.   line-height: 2;
  255.   margin-bottom: 10px;
  256.   position: relative;
  257. }
  258. .upload-file-list .ele-upload-list__item-content {
  259.   display: flex;
  260.   justify-content: space-between;
  261.   align-items: center;
  262.   color: inherit;
  263. }
  264. .ele-upload-list__item-content-action .el-link {
  265.   margin-right: 10px;
  266. }
  267. </style>
复制代码
3.图片回显

使用

  1. <ImagePreview :src="content.picUrl" :width="150" :height="150"></ImagePreview>
复制代码
封装代码

  1. <template>
  2.   <div>
  3.     <el-image v-for="(item,index) in realSrcList" :key="index"
  4.     :src="`${item}`"
  5.     fit="cover"
  6.     :style="`width:${realWidth};height:${realHeight};`"
  7.     :preview-src-list="realSrcList"
  8.   >
  9.     <div slot="error" class="image-slot">
  10.       <i class="el-icon-picture-outline"></i>
  11.     </div>
  12.   </el-image>
  13.   </div>
  14. </template>
  15. <script>
  16. export default {
  17.   name: "ImagePreview",
  18.   props: {
  19.     src: {
  20.       type: String,
  21.       default: ""
  22.     },
  23.     width: {
  24.       type: [Number, String],
  25.       default: ""
  26.     },
  27.     height: {
  28.       type: [Number, String],
  29.       default: ""
  30.     }
  31.   },
  32.   computed: {
  33.     realSrc() {
  34.       if (!this.src) {
  35.         return;
  36.       }
  37.       let real_src = this.src.split(",")[0];
  38.       return real_src;
  39.     },
  40.     realSrcList() {
  41.       if (!this.src) {
  42.         return;
  43.       }
  44.       let real_src_list = this.src.split(",");
  45.       let srcList = [];
  46.       real_src_list.forEach(item => {
  47.         return srcList.push(item);
  48.       });
  49.       return srcList;
  50.     },
  51.     realWidth() {
  52.       return typeof this.width == "string" ? this.width : `${this.width}px`;
  53.     },
  54.     realHeight() {
  55.       return typeof this.height == "string" ? this.height : `${this.height}px`;
  56.     }
  57.   },
  58. };
  59. </script>
  60. <style lang="scss" scoped>
  61. .el-image {
  62.   border-radius: 5px;
  63.   background-color: #ebeef5;
  64.   box-shadow: 0 0 5px 1px #ccc;
  65.   ::v-deep .el-image__inner {
  66.     transition: all 0.3s;
  67.     cursor: pointer;
  68.     &:hover {
  69.       transform: scale(1.2);
  70.     }
  71.   }
  72.   ::v-deep .image-slot {
  73.     display: flex;
  74.     justify-content: center;
  75.     align-items: center;
  76.     width: 100%;
  77.     height: 100%;
  78.     color: #909399;
  79.     font-size: 30px;
  80.   }
  81. }
  82. </style>
复制代码
4.文件回显

使用
  1.    <FileUpload v-model="content.fileIds" :isShowTip="false" :fileType="false" :isUpload="false"></FileUpload>
复制代码
5.树形封装

使用
  1. <orginTree v-model="form.deptId" @getdep="getdep"></orginTree>
复制代码
组件封装代码
  1. <template>
  2.   <div>
  3.     <a-tree-select
  4.       v-model="orgId"
  5.       style="width: 100%"
  6.       size="large"
  7.       :dropdown-style="{ maxHeight: '400px', overflow: 'auto', zIndex: 3000 }"
  8.       placeholder="请选择"
  9.       allow-clear
  10.       tree-default-expand-all
  11.       :disabled="disabled"
  12.       :tree-data="vorganTreeData"
  13.       :replaceFields="replaceFields"
  14.       @change="onChange"
  15.     >
  16.     </a-tree-select>
  17.   </div>
  18. </template>
  19. <script>
  20. //注意!!!!!
  21. //在modal弹窗组件中使用该组件需要在关闭弹窗方法里清空数据否则会报错
  22. import { userdepList } from "@/api/user/user";
  23. export default {
  24.   name: "vorganTree",
  25.   props: {
  26.     value: {
  27.       // 如果希望value可以接收int类型的值而不报错,可以将type类型修改为可以兼容字符串和整数的类型
  28.       type: [String, Number],
  29.       default: "",
  30.     },
  31.     disabled: {
  32.       type: Boolean,
  33.       default: false,
  34.     },
  35.     replaceFields: {
  36.       type: Object,
  37.       default: () => {
  38.         return {
  39.           children: "children",
  40.           title: "label",
  41.           key: "id",
  42.           value: "id",
  43.         };
  44.       },
  45.     },
  46.   },
  47.   data() {
  48.     return {
  49.       orgId: this.value,
  50.       vorganTreeData: [],
  51.       deptId: "",
  52.     };
  53.   },
  54.   watch: {
  55.     value: {
  56.       handler(newVal) {
  57.         this.orgId = newVal;
  58.       },
  59.       immediate: true,
  60.     },
  61.   },
  62.   mounted() {
  63.     // this.$bus.$on("id", (data) => {
  64.     //   console.log("我是任务组件,收到了数据", data);
  65.     //   this.deptId = data;
  66.     // });
  67.     this.deptId = this.$bus.id;
  68.     this.userdepList();
  69.   },
  70.   methods: {
  71.     userdepList() {
  72.       userdepList({ ancestors: this.deptId }).then((res) => {
  73.         console.log("res.data", res);
  74.         this.vorganTreeData = res.data;
  75.       });
  76.     },
  77.     selectClear() {
  78.       this.orgId = undefined;
  79.     },
  80.     onChange(value, item, xx) {
  81.       console.log(11111, value, item, xx);
  82.       // this.$emit("update:value", value);
  83.       this.$emit("getdep", value);
  84.     },
  85.   },
  86. };
  87. </script>
  88. <style scoped lang="less">
  89. </style>
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

tsx81428

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表