naiveui 的图片上传 原生写法非常繁琐,而且 不能自动拆分url,在多图上传的时候 很麻烦,所以我封装了一个上传图片的组件,分享给naive 使用者
<template><n-uploadref="uploadRef"v-model:file-list="fileList":action="action":headers="headers":max="max":disabled="disabled"list-type="image-card"@finish="handleUploadFinish"@error="handleUploadError"@remove="handleRemove">点击上传</n-upload>
</template><script setup>
import { ref, onMounted, nextTick } from 'vue';
import { useMessage } from 'naive-ui';const props = defineProps({initialIcon: {type: String,default: ''},max: {type: Number,default: 1},action: {type: String,default: '/api/manager/oss/upload'},disabled: {type: Boolean,default: false}
});const emits = defineEmits(['update:icon']);const message = useMessage();
const uploadRef = ref(null);
const ssoClient = useSSOClient();
const headers = ref({'x-token': `Bearer ${ssoClient.getToken()}`
});
const fileList = ref([]);const handleImageDisplay = (iconValue) => {if (iconValue) {const iconUrls = iconValue.split(',').filter(url => url.trim()!== '');return iconUrls.map((url, index) => ({id: `existing-${index}`,name: `image-${index}.png`,status: 'finished',url: url}));}return [];
};const handleUploadFinish = ({ file, event }) => {try {const response = JSON.parse(event.target.response);if (response.code === 200 || response.success) {const url = response.data.link;let newIcon = props.initialIcon;if (newIcon) {newIcon += ',' + url;} else {newIcon = url;}emits('update:icon', newIcon);message.success('上传成功');} else {message.error(response.message || '上传失败');removeFailedFile(file);}} catch (error) {message.error('上传失败: 无法解析响应');removeFailedFile(file);}
};const handleUploadError = ({ file }) => {message.error('上传失败');removeFailedFile(file);
};const handleRemove = ({ file }) => {if (file && file.url && props.initialIcon) {const urls = props.initialIcon.split(',').filter(url => url.trim()!== '');const updatedUrls = urls.filter(url => url!== file.url);const newIcon = updatedUrls.join(',');emits('update:icon', newIcon);message.success('图片已删除');}
};const removeFailedFile = (file) => {if (file && file.id) {const newFileList = fileList.value.filter(f => f.id!== file.id);fileList.value = [...newFileList];nextTick(() => {if (uploadRef.value && typeof uploadRef.value.clear === 'function') {uploadRef.value.clear();fileList.value = newFileList;}});}
};onMounted(() => {fileList.value = handleImageDisplay(props.initialIcon);
});
</script>
<NFormItemGi :span="8" label="身份证照片" path="idCardPhoto"><ImageUpload:initial-icon="formValue.idCardPhoto"@update:icon="formValue.idCardPhoto = $event":max="3"/></NFormItemGi>
只要是 绑定这个 formValue.idCardPhoto 你所需要的 字段 就行