初始化
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
<script lang="ts" setup>
|
||||
import type { UploadProps } from 'element-plus';
|
||||
|
||||
import { ref, watch } from 'vue';
|
||||
|
||||
import { useAppConfig } from '@easyflow/hooks';
|
||||
import { useAccessStore } from '@easyflow/stores';
|
||||
|
||||
import { Plus } from '@element-plus/icons-vue';
|
||||
import { ElIcon, ElImage, ElMessage, ElUpload } from 'element-plus';
|
||||
|
||||
const props = defineProps({
|
||||
action: {
|
||||
type: String,
|
||||
default: '/api/v1/commons/upload',
|
||||
},
|
||||
fileSize: {
|
||||
type: Number,
|
||||
default: 2,
|
||||
},
|
||||
allowedImageTypes: {
|
||||
type: Array<string>,
|
||||
default: () => ['image/gif', 'image/jpeg', 'image/png', 'image/webp'],
|
||||
},
|
||||
modelValue: { type: String, default: '' },
|
||||
});
|
||||
|
||||
const emit = defineEmits(['success', 'update:modelValue']);
|
||||
const accessStore = useAccessStore();
|
||||
const headers = ref({
|
||||
'easyflow-token': accessStore.accessToken,
|
||||
});
|
||||
|
||||
const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
|
||||
const localImageUrl = ref(props.modelValue);
|
||||
const handleAvatarSuccess: UploadProps['onSuccess'] = (
|
||||
_response,
|
||||
uploadFile,
|
||||
) => {
|
||||
localImageUrl.value = URL.createObjectURL(uploadFile.raw!);
|
||||
emit('success', _response.data.path);
|
||||
emit('update:modelValue', _response.data.path);
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(newVal) => {
|
||||
localImageUrl.value = newVal;
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
|
||||
if (!props.allowedImageTypes.includes(rawFile.type)) {
|
||||
const formatTypes = props.allowedImageTypes
|
||||
.map((type: string) => {
|
||||
const parts = type.split('/');
|
||||
return parts[1] ? parts[1].toUpperCase() : '';
|
||||
})
|
||||
.filter(Boolean);
|
||||
ElMessage.error(`头像只能是${formatTypes.join(', ')}格式`);
|
||||
return false;
|
||||
} else if (rawFile.size / 1024 / 1024 > props.fileSize) {
|
||||
ElMessage.error(`头像限制 ${props.fileSize} M`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ElUpload
|
||||
class="avatar-uploader"
|
||||
:action="`${apiURL}${props.action}`"
|
||||
:headers="headers"
|
||||
:show-file-list="false"
|
||||
:on-success="handleAvatarSuccess"
|
||||
:before-upload="beforeAvatarUpload"
|
||||
>
|
||||
<ElImage
|
||||
v-if="localImageUrl"
|
||||
:src="localImageUrl"
|
||||
class="avatar"
|
||||
fit="cover"
|
||||
/>
|
||||
<ElIcon v-else class="avatar-uploader-icon"><Plus /></ElIcon>
|
||||
</ElUpload>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.avatar-uploader .avatar {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>
|
||||
.avatar-uploader .el-upload {
|
||||
border: 1px dashed var(--el-border-color);
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: var(--el-transition-duration-fast);
|
||||
}
|
||||
|
||||
.avatar-uploader .el-upload:hover {
|
||||
border-color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
.el-icon.avatar-uploader-icon {
|
||||
font-size: 28px;
|
||||
color: var(--el-text-color-secondary);
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user