//UPLOAD_URL 保存 地址
<template>
<el-upload
ref="uploadEl"
v-loading="isLoading"
:disabled="disabled"
:action="UPLOAD_URL"
:data="submitData"
:accept="accept"
:multiple="false"
:show-file-list="false"
:before-upload="beforeUpload"
:on-success="onSuccess"
:on-error="onError"
:class="disabled ? 'uploader--disabled' : ''"
:style="styleUploader"
class="uploader"
v-bind="$attrs"
v-on="$listeners"
>
<template v-if="url">
<img :src="url" class="uploader_image" :style="imgStyle" />
<el-image-viewer v-if="isShowPreview" :url-list="[url]" :on-close="onClosePreview" />
<div class="uploader_icon-group" @click.stop>
<i class="el-icon-zoom-in uploader_icon" @click="onPreview"></i>
<i v-if="!disabled" class="el-icon-delete uploader_icon" @click="onRemove"></i>
</div>
</template>
<i v-else class="el-icon-plus uploader_plus"></i>
</el-upload>
</template>
<script>
import { getQiNiuToken } from "@/api";
import ElImageViewer from "element-ui/packages/image/src/image-viewer";
import emitter from "@/mixins/emitter.js";
export default {
mixins: [emitter],
model: {
prop: "url",
event: "change",
},
components: {
ElImageViewer,
},
props: {
url: {
type: String,
default: "",
},
disabled: {
type: Boolean,
default: false,
},
size: {
type: Number,
default: 2,
},
accept: {
type: String,
default: "image/png, image/jpg, image/jpeg",
},
width: {
type: String,
default: "100px",
},
height: {
type: String,
default: "100px",
},
imgStyle: {
type: Object,
default() {
return {};
},
},
},
data() {
return {
UPLOAD_URL: process.env.VUE_APP_UPLOAD_URL,
STATIC_URL: process.env.VUE_APP_STATIC_URL,
submitData: {
token: "",
},
isLoading: false,
// preview
isShowPreview: false,
};
},
computed: {
styleUploader() {
const min = Math.min(parseFloat(this.width), parseFloat(this.height));
return {
"--uploader-width": this.width,
"--uploader-height": this.height,
"--uploader-font-size": min > 100 ? "20px" : "16px",
};
},
},
methods: {
// before upload
async beforeUpload() {
// const isLt2M = file.size / 1024 / 1024 < this.size;
// if (!isLt2M) {
// this.$message.error(`上传图片大小不能超过 ${this.size}M!`);
// return false;
// }
this.isLoading = true;
try {
this.submitData.token = await this.getSubmitData();
} catch (error) {
this.isLoading = false;
}
},
// get qiniu token
async getSubmitData() {
const res = await getQiNiuToken();
if (res.code === "1") {
return res.data.object;
} else {
return "";
}
},
// upload success
onSuccess(res) {
this.isLoading = false;
this.$emit("change", this.STATIC_URL + "/" + res.key); //实际拼接地址
this.dispatch("ElFormItem", "el.form.change");
},
// upload error
onError(err) {
this.isLoading = false;
console.log(err);
},
// remove
onRemove() {
this.$emit("change", "");
this.dispatch("ElFormItem", "el.form.change");
},
// preview image
onPreview() {
this.isShowPreview = true;
},
// close preview image
onClosePreview() {
this.isShowPreview = false;
},
// chose
onChoose() {
this.$refs.uploadEl?.$refs["upload-inner"]?.handleClick();
},
},
};
</script>
<style lang="scss" scoped>
.uploader {
--uploader-width: 100px;
--uploader-height: 100px;
--uploader-font-size: 16px;
position: relative;
box-sizing: content-box;
width: var(--uploader-width);
height: var(--uploader-height);
overflow: hidden;
line-height: 0;
border-radius: 5px;
border: 1px dashed var(--border-color);
::v-deep {
.el-upload {
width: 100%;
height: 100%;
}
.el-upload-dragger {
width: 100%;
height: 100%;
border: none;
}
}
.uploader_plus {
display: block;
box-sizing: border-box;
width: 100%;
height: 100%;
line-height: var(--uploader-height);
border-radius: 4px;
font-size: 28px;
color: #8c939d;
text-align: center;
}
.uploader_image {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
.uploader_icon-group {
position: absolute;
left: 0;
right: 0;
bottom: 0;
color: #fff;
opacity: 0;
background-color: rgba(0, 0, 0, 0.5);
transition: opacity 0.3s;
cursor: default;
}
.uploader_icon {
padding: 5px;
font-size: var(--uploader-font-size);
cursor: pointer;
& + .uploader_icon {
margin-left: 15px;
}
&:hover {
color: $color-primary;
}
}
&:hover {
.uploader_icon-group {
opacity: 1;
}
}
&.uploader--disabled:hover {
::v-deep .el-upload {
cursor: not-allowed;
}
}
&:not(.uploader--disabled):hover {
border-color: $color-primary;
.uploader_plus:hover {
color: $color-primary;
}
}
}
</style>
<style lang="scss">
.el-form-item.is-error .uploader:not(.uploader--disabled) {
border-color: $color-danger;
}
</style>
//使用
//引入
import UploadImg from "@/components/element/upload/Image";
//声明
components: {
UploadImg,
},
//使用
<UploadImg v-model="formData.ownImg" width="260px" height="260px" />
//import emitter from "@/mixins/emitter.js";
export default {
methods: {
dispatch(componentName, eventName, params) {
var parent = this.$parent || this.$root;
var name = parent.$options.componentName;
while (parent && (!name || name !== componentName)) {
parent = parent.$parent;
if (parent) {
name = parent.$options.componentName;
}
}
if (parent) {
parent.$emit.apply(parent, [eventName].concat(params));
}
},
},
};