前言
LUpload 组件
- 首先我们在 components 创建一个文件名为 LUpload.vue 的文件
- 代码如下
<template>
<div class="l-upload" :class="round ? 'round' : ''">
<el-upload class="avatar-uploader" :style="uploadStyle" :headers="headers" :action="action" :show-file-list="false"
:on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload" :on-progress="handleAvatarProgress"
v-loading="uploadLoading">
<div class="avatar" v-if="modelValue" @click.stop>
<el-image class="image" :src="modelValue" ref="imageRef" />
<div class="el-upload-actions">
<div class="item" @click="handlePictureCardPreview">
<el-icon size="18" color="#fff">
<ZoomIn />
</el-icon>
</div>
<div class="item" @click="handleRemove">
<el-icon size="18" color="#fff">
<Delete />
</el-icon>
</div>
</div>
</div>
<el-icon v-else class="avatar-uploader-icon">
<Plus />
</el-icon>
</el-upload>
<ElImageViewer v-if="isImageView" :url-list="srcList" @close="imageClose"></ElImageViewer>
</div>
</template>
<script setup lang="ts">
import { defineProps, reactive, ref, toRefs, defineEmits } from 'vue'
import { Plus, ZoomIn, Delete } from '@element-plus/icons-vue'
import { ElImageViewer } from 'element-plus';
import { getDomainName } from "@/utils/index";
import Cookies from 'js-cookie'
const props = defineProps({
modelValue: {
type: String
},
action: {
type: String,
default: 'http://127.0.0.1:1024/image/upload'
},
uploadStyle: {
type: Object,
default: {
width: "200px",
height: "200px",
}
},
round: {
type: Boolean,
default: false
}
})
const state = reactive({
uploadLoading: false,
headers: {
Authorization: Cookies.get('Token'),
ContentType: 'application/json;charset=utf-8'
},
isImageView: false,
srcList: [] as any
})
const { headers, uploadLoading, isImageView, srcList } = toRefs(state)
const imageRef = ref()
const emit = defineEmits(['update:modelValue'])
function handlePictureCardPreview() {
state.isImageView = true
}
function imageClose() {
state.isImageView = false
state.srcList = []
}
function handleRemove() {
emit('update:modelValue', "")
}
function handleAvatarSuccess(response: any, file: any, fileList: any) {
let url = getDomainName() + response.data.url
emit('update:modelValue', url)
state.srcList.push(url)
state.uploadLoading = false
}
function beforeAvatarUpload() {
}
function handleAvatarProgress() {
state.uploadLoading = true
}
</script>
<style scoped lang="scss">
.l-upload {
::v-deep .el-upload {
width: 100%;
height: 100%;
border: 1px dashed #dcdfe6;
}
.avatar-uploader {
.avatar {
width: 100%;
height: 100%;
cursor: auto;
position: relative;
.image {
width: 100%;
height: 100%;
}
.el-upload-actions {
top: 0;
left: 0;
cursor: auto;
width: 100%;
height: 100%;
transition: 0.5s;
position: absolute;
background: rgba($color: #000000, $alpha: 0.5);
opacity: 0;
display: flex;
align-items: center;
justify-content: center;
.item {
width: 30px;
height: 30px;
display: flex;
cursor: pointer;
align-items: center;
justify-content: center;
}
}
&:hover {
.el-upload-actions {
opacity: 1;
display: flex;
align-items: center;
justify-content: center;
}
}
}
}
}
.round {
::v-deep .el-upload {
border-radius: 50px;
overflow: hidden;
}
}
</style>
父组件,LUpload.vue的使用
- 首先我们肯定需要先引入一下 LUpload.vue 组件了
<template>
<div class="dashboard">
<LUpload v-model="url"></LUpload>
</div>
</template>
<script setup lang="ts">
import { reactive, toRefs, ref, onMounted } from 'vue'
import LUpload from "@/components/LUpload/index.vue"
const state = reactive({
url: ""
})
const { url } = toRefs(state)
onMounted(() => {
})
</script>
<style scoped lang="scss">
.bg {
width: 100px;
height: 100px;
}
</style>
接下来我们看一下效果吧
有点模糊,就这样看吧。