美丽的神话 发表于 2024-9-13 12:29:33

vue3中antd上传图片组件及回显

实现结果:
https://i-blog.csdnimg.cn/direct/ffae0154747744f8ab9339492ce59e2b.png
调用后端接口后,后端返回的数据:https://i-blog.csdnimg.cn/direct/bcd0d1657fdc4ac8ace7dd9fe41a1dfa.png
1.在项目components/base下新建UploadNew.vue文件(上传图片公共组件)
<template>
<div class="clearfix">
    <a-upload
      v-model:file-list="fileList"
      action="/platform-gateway/platform-file/security/chain"
      list-type="picture-card"
       :headers="headers"
      @preview="handlePreview"
      @change="handleChange"
    >
      <div v-if="fileList.length < props.limit">
      <plus-outlined />
      <div style="margin-top: 8px">上传</div>
      </div>
    </a-upload>
    <a-modal :open="previewVisible" :title="previewTitle" :footer="null" @cancel="handleCancel">
      <img alt="example" style="width: 100%" :src="previewImage" />
    </a-modal>
</div>
</template>
<script lang="ts" setup>
import { PlusOutlined } from '@ant-design/icons-vue';
import { ref } from 'vue';
import type { UploadChangeParam, UploadProps } from 'ant-design-vue';
import { HttpClientUtils } from '../../configure/http/httpClientUtils'

interface Props {
accept: string, // 上传文件的格式,
limit: number,//上传图片数量
fileListJson :UploadProps['fileList']
}
const props = defineProps<Props>()
function getBase64(file: File) {
return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = error => reject(error);
});
}

const previewVisible = ref(false);
const previewImage = ref('');
const previewTitle = ref('');
//调用后端接口请求头
const headers = {
    authorization: HttpClientUtils.getToken(),
    platform: 'WEB',
    serviceCode: 'athletics-service'
}
const $emit = defineEmits(["uploadDone"])
const fileList = ref<UploadProps['fileList']>([

]);
if (props.fileListJson) {
    fileList.value = props.fileListJson
}
const handleCancel = () => {
previewVisible.value = false;
previewTitle.value = '';
};

const handlePreview = async (file: UploadProps['fileList']) => {
if (!file.url && !file.preview) {
    file.preview = (await getBase64(file.originFileObj)) as string;
}
previewImage.value = file.url || file.preview;
previewVisible.value = true;
previewTitle.value = file.name || file.url.substring(file.url.lastIndexOf('/') + 1);
};

const handleChange = (info: UploadChangeParam) => {
if (info.file.status === 'done') {
    //   imageId.value = 'http://192.168.5.13/platform-gateway/platform-file/security/chain?fileName=' + info.file.response.data + '&serviceCode=athletics-service'
      $emit("uploadDone", info.fileList)
}
};
</script>

<style scoped>
/* you can make up upload button and sample style by using stylesheets */
.ant-upload-select-picture-card i {
font-size: 32px;
color: #999;
}

.ant-upload-select-picture-card .ant-upload-text {
margin-top: 8px;
color: #666;
}
</style>
2.页面中使用
先引入:import AntdUploadFile  from "@/components/base/UploadNew.vue";
定义:
const props = defineProps({
  data: {} as any,
})//点编辑时父组件传入的回显数据
const fileListJson = ref<UploadProps['fileList']>([]);//封面
const fileListJson1 = ref<UploadProps['fileList']>([]);//轮播图
const formData = reactive({
venue: {
    headerUrl:props.data?.headerUrl,
    bannerUrl:props.data?.bannerUrl,
},
}) 2.1 表单样式、使用组件
<a-form-item :name="['venue', 'headerUrl']" label="封面图" :rules="[{ required: true }]">
      <AntdUploadFile
      :fileListJson="fileListJson"
      :limit="1"
      accept=""
      type="frontIdcard"
      @upload-load="onUploading"
      @upload-done="onUploadDone"
      >
      </AntdUploadFile>

    </a-form-item>
    <a-form-item :name="['venue', 'bannerUrl']" label="场馆轮播" :rules="[{ required: true }]">
    <AntdUploadFile
      :limit="4"
      accept=""
      :fileListJson="fileListJson1"
      type="frontIdcard1"
      @upload-load="onUploading1"
      @upload-done="onUploadDone1"
      >
      </AntdUploadFile>
    </a-form-item> 2.2 上传图片成功 ,点保存后传给后端
// 封面图片上传成功(单个图)
const onUploadDone = (fileList: any) => {
// 文件上传成功后返回的文件信息 type,是为了一个页面引用多少文件上传作的区分
if (fileList.length) {
      formData.venue.headerUrl= fileList.response.data

}
console.log( formData.venue.headerUrl,"上传成功后的参数 ", fileList);
}
// 轮播图片上传成功(多张图)
const onUploadDone1 = (fileList: any) => {
// 文件上传成功后返回的文件信息 type,是为了一个页面引用多少文件上传作的区分
let bannerUrl = []
if (fileList.length) {
    for (let i = 0; i < fileList.length; i++) {
      if (fileList.response) {
               bannerUrl.push({
               "url":fileList.response.data,
            })
      } else {
   //将fileName= 后面的数据和&前的数据截取push到url后,转为json字符串传给后端
      const index = fileList.url.indexOf('fileName=')
      let newIndex: any
      if (index !== -1) {
          const start = fileList.url.slice(index + 'fileName='.length)
          const endIndex = start.indexOf('&')
          if (endIndex !== -1) {
            newIndex = start.slice(0,endIndex)
          }
      }
          bannerUrl.push({
            "url": newIndex,
         })
         }   
       }
}
formData.venue.bannerUrl =JSON.stringify(bannerUrl)
} 2.3 点编辑时回显(因本接口后端返回的数据需要拼接,可根据自行情况修改)
if (props.data.bannerUrl||props.data.headerUrl) {
            fileListJson.value.push({
               "url":'http://platform-file/security/chain?fileName=' + props.data.headerUrl + '&serviceCode=athletics-service',
            })
const bannerList =JSON.parse(props.data.bannerUrl)//json字符串转为数组
console.log(bannerList,'里面有这个图片吗')
            for (let i = 0;i< bannerList.length;i++) {
            fileListJson1.value.push({
               "url":'后端返回的地址',
            })
}

}

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: vue3中antd上传图片组件及回显