perf: 头像上传参数

This commit is contained in:
2023-07-21 16:49:21 +08:00
parent d2c0203f07
commit da0a9144b0
3 changed files with 41 additions and 15 deletions

View File

@ -14,7 +14,7 @@
</div> </div>
</slot> </slot>
</div> </div>
<el-dialog v-model="showDialog" title="上传头像" width="800px" append-to-body @opened="modalOpened" @closed="closeDialog"> <el-dialog v-if="!disabled" v-model="showDialog" title="上传头像" width="800px" append-to-body @opened="modalOpened" @closed="closeDialog">
<el-row> <el-row>
<el-col :xs="24" :md="12" :style="{ height: '350px' }"> <el-col :xs="24" :md="12" :style="{ height: '350px' }">
<VueCropper <VueCropper
@ -71,7 +71,8 @@ import { Minus, Plus, RefreshLeft, RefreshRight, Upload } from '@element-plus/ic
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
accpet?: string accpet?: string
modelValue?: string fileId?: number | string
fileUrl?: string
/** /**
* 图片大小单位MB * 图片大小单位MB
* *
@ -82,23 +83,29 @@ const props = withDefaults(defineProps<{
autoCropHeight?: number autoCropHeight?: number
/** 默认生成截图框高度 */ /** 默认生成截图框高度 */
autoCropWidth?: number autoCropWidth?: number
/** 上传请求函数 */
uploadFunction?: (formData: FormData) => Promise<FileVO> uploadFunction?: (formData: FormData) => Promise<FileVO>
/** 文件信息请求函数 */
fileFunction: (fileId?: number | string) => Promise<FileVO>
disabled?: boolean disabled?: boolean
}>(), { }>(), {
accpet: '.jpeg,.jpg,.png,.bmp', accpet: '.jpeg,.jpg,.png,.bmp',
fileId: '',
fileUrl: '',
fileSize: 2, fileSize: 2,
autoCropHeight: 200, autoCropHeight: 200,
autoCropWidth: 200, autoCropWidth: 200,
uploadFunction: () => Promise.resolve({}),
}) })
const emit = defineEmits<{ const emit = defineEmits<{
(event: 'update:modelValue', modelValue?: string): void (event: 'update:fileUrl', fileId?: number): void
(event: 'update:filelId', modelValue?: string): void
(event: 'onSuccess', file: FileVO): void (event: 'onSuccess', file: FileVO): void
(event: 'onError', error: Error): void (event: 'onError', error: Error): void
}>() }>()
const avatarUrl = useVModel(props, 'modelValue', emit) let avatarUrl = $ref(props.fileUrl)
const filelId = useVModel(props, 'fileId', emit)
const imageStyle = computed(() => ({ const imageStyle = computed(() => ({
height: `${props.autoCropHeight}px`, height: `${props.autoCropHeight}px`,
@ -182,8 +189,14 @@ function selectImage() {
} }
async function uploadImg(blob: Blob) { async function uploadImg(blob: Blob) {
if (!props.uploadFunction) {
ElMessage.error('请定义接口请求函数')
emit('onError', new Error('请定义接口请求函数'))
return
}
if (blob.size > props.fileSize * 1024 * 1024) { if (blob.size > props.fileSize * 1024 * 1024) {
ElMessage.error('您的图片经过剪裁依然很大,请重新选择图片') ElMessage.error('您的图片经过剪裁依然很大,请重新选择图片')
emit('onError', new Error('您的图片经过剪裁依然很大,请重新选择图片'))
return return
} }
@ -193,7 +206,8 @@ async function uploadImg(blob: Blob) {
try { try {
const res = await props.uploadFunction(formData) const res = await props.uploadFunction(formData)
avatarUrl.value = res.url avatarUrl = res.url
filelId.value = res.id
showDialog = false showDialog = false
emit('onSuccess', res) emit('onSuccess', res)
} }
@ -212,6 +226,14 @@ function closeDialog() {
reset() reset()
loading = false loading = false
} }
watch(() => props.fileId, async () => {
if (!props.fileId || avatarUrl)
return
const res = await props.fileFunction(props.fileId)
avatarUrl = res.url
})
</script> </script>
<style> <style>

View File

@ -2,7 +2,7 @@
* @Author: zhaojinfeng 121016171@qq.com * @Author: zhaojinfeng 121016171@qq.com
* @Date: 2023-07-18 12:28:36 * @Date: 2023-07-18 12:28:36
* @LastEditors: zhaojinfeng 121016171@qq.com * @LastEditors: zhaojinfeng 121016171@qq.com
* @LastEditTime: 2023-07-20 17:13:00 * @LastEditTime: 2023-07-21 16:34:51
* @FilePath: \vue3\stories\UploadAvatar.stories.ts * @FilePath: \vue3\stories\UploadAvatar.stories.ts
* @Description: * @Description:
* *
@ -16,7 +16,8 @@ const meta = {
component: ThUploadAvatar, component: ThUploadAvatar,
tags: ['autodocs'], tags: ['autodocs'],
args: { args: {
modelValue: '', fileId: '',
fileUrl: '',
accpet: '.jpeg,.jpg,.png,.bmp', accpet: '.jpeg,.jpg,.png,.bmp',
disabled: false, disabled: false,
fileSize: 2, fileSize: 2,
@ -43,7 +44,7 @@ export const Base: Story = {
export const Preview: Story = { export const Preview: Story = {
name: '启用disabled当做预览组件', name: '启用disabled当做预览组件',
args: { args: {
modelValue: avatar, fileUrl: avatar,
disabled: false, disabled: true,
}, },
} }

13
types/components.d.ts vendored
View File

@ -8,12 +8,12 @@ export {}
declare module 'vue' { declare module 'vue' {
export interface GlobalComponents { export interface GlobalComponents {
DownloadLink: typeof import('./../packages/download-link/index.vue')['default'] DownloadLink: typeof import('./../packages/download-link/index.vue')['default']
ElAvatar: typeof import('element-plus/es')['ElAvatar']
ElButton: typeof import('element-plus/es')['ElButton'] ElButton: typeof import('element-plus/es')['ElButton']
ElCol: typeof import('element-plus/es')['ElCol'] ElInput: typeof import('element-plus/es')['ElInput']
ElDialog: typeof import('element-plus/es')['ElDialog'] ElLink: typeof import('element-plus/es')['ElLink']
ElIcon: typeof import('element-plus/es')['ElIcon'] ElPopconfirm: typeof import('element-plus/es')['ElPopconfirm']
ElRow: typeof import('element-plus/es')['ElRow'] ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
Header: typeof import('./../packages/header/index.vue')['default'] Header: typeof import('./../packages/header/index.vue')['default']
PreviewOffice: typeof import('./../packages/preview-office/index.vue')['default'] PreviewOffice: typeof import('./../packages/preview-office/index.vue')['default']
PreviewOfficeView: typeof import('./../packages/preview-office-view/index.vue')['default'] PreviewOfficeView: typeof import('./../packages/preview-office-view/index.vue')['default']
@ -24,4 +24,7 @@ declare module 'vue' {
UploadSingleFile: typeof import('./../packages/upload-single-file/index.vue')['default'] UploadSingleFile: typeof import('./../packages/upload-single-file/index.vue')['default']
UploadTable: typeof import('./../packages/upload-table/index.vue')['default'] UploadTable: typeof import('./../packages/upload-table/index.vue')['default']
} }
export interface ComponentCustomProperties {
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
}
} }