ImageUpload组件支持多图片上传
This commit is contained in:
		
							parent
							
								
									e259093e01
								
							
						
					
					
						commit
						f56da498ab
					
				| 
						 | 
					@ -163,13 +163,14 @@ export default {
 | 
				
			||||||
        return "";
 | 
					        return "";
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    // 对象转成分隔字符串
 | 
					    // 对象转成指定字符串分隔
 | 
				
			||||||
    listToString(list) {
 | 
					    listToString(list, separator) {
 | 
				
			||||||
      let files = "";
 | 
					      let strs = "";
 | 
				
			||||||
      for (let key in list) {
 | 
					      separator = separator || ",";
 | 
				
			||||||
        files += list[key].url + ",";
 | 
					      for (let i in list) {
 | 
				
			||||||
 | 
					        strs += list[i].url + separator;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      return files.substr(0, files.length - 1);
 | 
					      return strs != '' ? strs.substr(0, strs.length - 1) : '';
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,33 +5,38 @@
 | 
				
			||||||
      list-type="picture-card"
 | 
					      list-type="picture-card"
 | 
				
			||||||
      :on-success="handleUploadSuccess"
 | 
					      :on-success="handleUploadSuccess"
 | 
				
			||||||
      :before-upload="handleBeforeUpload"
 | 
					      :before-upload="handleBeforeUpload"
 | 
				
			||||||
 | 
					      :limit="limit"
 | 
				
			||||||
      :on-error="handleUploadError"
 | 
					      :on-error="handleUploadError"
 | 
				
			||||||
 | 
					      :on-exceed="handleExceed"
 | 
				
			||||||
      name="file"
 | 
					      name="file"
 | 
				
			||||||
      :show-file-list="false"
 | 
					      :on-remove="handleRemove"
 | 
				
			||||||
 | 
					      :show-file-list="true"
 | 
				
			||||||
      :headers="headers"
 | 
					      :headers="headers"
 | 
				
			||||||
      style="display: inline-block; vertical-align: top"
 | 
					      :file-list="fileList"
 | 
				
			||||||
 | 
					      :on-preview="handlePictureCardPreview"
 | 
				
			||||||
 | 
					      :class="{hide: this.fileList.length >= this.limit}"
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <el-image v-if="!value" :src="value">
 | 
					      <i class="el-icon-plus"></i>
 | 
				
			||||||
        <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="预览" @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-upload>
 | 
				
			||||||
    <el-dialog :visible.sync="dialogVisible" title="预览" width="800" append-to-body>
 | 
					    
 | 
				
			||||||
      <img :src="value" style="display: block; max-width: 100%; margin: 0 auto;">
 | 
					    <!-- 上传提示 -->
 | 
				
			||||||
 | 
					    <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>
 | 
					    </el-dialog>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
| 
						 | 
					@ -40,36 +45,128 @@
 | 
				
			||||||
import { getToken } from "@/utils/auth";
 | 
					import { getToken } from "@/utils/auth";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					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() {
 | 
					  data() {
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
 | 
					      dialogImageUrl: "",
 | 
				
			||||||
      dialogVisible: false,
 | 
					      dialogVisible: false,
 | 
				
			||||||
 | 
					      hideUpload: false,
 | 
				
			||||||
 | 
					      baseUrl: process.env.VUE_APP_BASE_API,
 | 
				
			||||||
      uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
 | 
					      uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
 | 
				
			||||||
      headers: {
 | 
					      headers: {
 | 
				
			||||||
        Authorization: "Bearer " + getToken(),
 | 
					        Authorization: "Bearer " + getToken(),
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
					      fileList: []
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  props: {
 | 
					  watch: {
 | 
				
			||||||
    value: {
 | 
					    value: {
 | 
				
			||||||
      type: String,
 | 
					      handler(val) {
 | 
				
			||||||
      default: "",
 | 
					        if (val) {
 | 
				
			||||||
 | 
					          // 首先将值转为数组
 | 
				
			||||||
 | 
					          const list = Array.isArray(val) ? val : this.value.split(',');
 | 
				
			||||||
 | 
					          // 然后将数组转为对象数组
 | 
				
			||||||
 | 
					          this.fileList = list.map(item => {
 | 
				
			||||||
 | 
					            if (typeof item === "string") {
 | 
				
			||||||
 | 
					              if (item.indexOf(this.baseUrl) === -1) {
 | 
				
			||||||
 | 
					                  item = { name: this.baseUrl + item, url: this.baseUrl + item };
 | 
				
			||||||
 | 
					              } else {
 | 
				
			||||||
 | 
					                  item = { name: item, url: item };
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return item;
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          this.fileList = [];
 | 
				
			||||||
 | 
					          return [];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      deep: true,
 | 
				
			||||||
 | 
					      immediate: true
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  computed: {
 | 
				
			||||||
 | 
					    // 是否显示提示
 | 
				
			||||||
 | 
					    showTip() {
 | 
				
			||||||
 | 
					      return this.isShowTip && (this.fileType || this.fileSize);
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  methods: {
 | 
					  methods: {
 | 
				
			||||||
    removeImage() {
 | 
					    // 删除图片
 | 
				
			||||||
      this.$emit("input", "");
 | 
					    handleRemove(file, fileList) {
 | 
				
			||||||
 | 
					      const findex = this.fileList.indexOf(file.name);
 | 
				
			||||||
 | 
					      this.fileList.splice(findex, 1);
 | 
				
			||||||
 | 
					      this.$emit("input", this.listToString(this.fileList));
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    // 上传成功回调
 | 
				
			||||||
    handleUploadSuccess(res) {
 | 
					    handleUploadSuccess(res) {
 | 
				
			||||||
      this.$emit("input", res.url);
 | 
					      this.fileList.push({ name: res.fileName, url: res.fileName });
 | 
				
			||||||
 | 
					      this.$emit("input", this.listToString(this.fileList));
 | 
				
			||||||
      this.loading.close();
 | 
					      this.loading.close();
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    handleBeforeUpload() {
 | 
					    // 上传前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.$message.error(
 | 
				
			||||||
 | 
					          `文件格式不正确, 请上传${this.fileType.join("/")}图片格式文件!`
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (this.fileSize) {
 | 
				
			||||||
 | 
					        const isLt = file.size / 1024 / 1024 < this.fileSize;
 | 
				
			||||||
 | 
					        if (!isLt) {
 | 
				
			||||||
 | 
					          this.$message.error(`上传头像图片大小不能超过 ${this.fileSize} MB!`);
 | 
				
			||||||
 | 
					          return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      this.loading = this.$loading({
 | 
					      this.loading = this.$loading({
 | 
				
			||||||
        lock: true,
 | 
					        lock: true,
 | 
				
			||||||
        text: "上传中",
 | 
					        text: "上传中",
 | 
				
			||||||
        background: "rgba(0, 0, 0, 0.7)",
 | 
					        background: "rgba(0, 0, 0, 0.7)",
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    // 文件个数超出
 | 
				
			||||||
 | 
					    handleExceed() {
 | 
				
			||||||
 | 
					      this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`);
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // 上传失败
 | 
				
			||||||
    handleUploadError() {
 | 
					    handleUploadError() {
 | 
				
			||||||
      this.$message({
 | 
					      this.$message({
 | 
				
			||||||
        type: "error",
 | 
					        type: "error",
 | 
				
			||||||
| 
						 | 
					@ -77,24 +174,37 @@ export default {
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
      this.loading.close();
 | 
					      this.loading.close();
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  },
 | 
					    // 预览
 | 
				
			||||||
  watch: {},
 | 
					    handlePictureCardPreview(file) {
 | 
				
			||||||
 | 
					      this.dialogImageUrl = file.url;
 | 
				
			||||||
 | 
					      this.dialogVisible = true;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // 对象转成指定字符串分隔
 | 
				
			||||||
 | 
					    listToString(list, separator) {
 | 
				
			||||||
 | 
					      let strs = "";
 | 
				
			||||||
 | 
					      separator = separator || ",";
 | 
				
			||||||
 | 
					      for (let i in list) {
 | 
				
			||||||
 | 
					        strs += list[i].url + separator;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return strs != '' ? strs.substr(0, strs.length - 1) : '';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					 | 
				
			||||||
<style scoped lang="scss">
 | 
					<style scoped lang="scss">
 | 
				
			||||||
.image {
 | 
					// .el-upload--picture-card 控制加号部分
 | 
				
			||||||
  position: relative;
 | 
					::v-deep.hide .el-upload--picture-card {
 | 
				
			||||||
  .mask {
 | 
					    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;
 | 
					    opacity: 0;
 | 
				
			||||||
    position: absolute;
 | 
					    transform: translateY(0);
 | 
				
			||||||
    top: 0;
 | 
					 | 
				
			||||||
    width: 100%;
 | 
					 | 
				
			||||||
    background-color: rgba(0, 0, 0, 0.5);
 | 
					 | 
				
			||||||
    transition: all 0.3s;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  &:hover .mask {
 | 
					 | 
				
			||||||
    opacity: 1;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,9 +73,9 @@ export default {
 | 
				
			||||||
            if(router.path === "/") {
 | 
					            if(router.path === "/") {
 | 
				
			||||||
              router.children[item].path = "/redirect/" + router.children[item].path;
 | 
					              router.children[item].path = "/redirect/" + router.children[item].path;
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
			  if(!this.ishttp(router.children[item].path)) {
 | 
					              if(!this.ishttp(router.children[item].path)) {
 | 
				
			||||||
                router.children[item].path = router.path + "/" + router.children[item].path;
 | 
					                router.children[item].path = router.path + "/" + router.children[item].path;
 | 
				
			||||||
			  }
 | 
					              }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            router.children[item].parentPath = router.path;
 | 
					            router.children[item].parentPath = router.path;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue