naiveui 的图片上传 原生写法非常繁琐,而且 不能自动拆分url,在多图上传的时候  很麻烦,所以我封装了一个上传图片的组件,分享给naive 使用者

<template>
  <n-upload
    ref="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  你所需要的  字段 就行  

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐