一、文件上传组件 Upload.vue <template> <el-upload drag action="#" list-type="picture-card" multiple :limit="1" :on-change="handleUpload" :class="{disabled:uploadDisabled}" :file-list="fileListCopy.data" :http-request="upload"> <span class="el-upload__text"> <em>点击<el-icon><Plus /></el-icon>上传</em> <br>或拖拽至此 </span> <template #file="{ file }"> <div> <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" /> <span class="el-upload-list__item-actions"> <span class="el-upload-list__item-preview" @click="handlePreview(file)"> <el-icon><zoom-in /></el-icon> </span> <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)"> <el-icon><Delete /></el-icon> </span> </span> </div> </template> </el-upload> <el-dialog v-model="dialogVisible"> <img w-full :src="dialogImageUrl" alt="Preview Image" /> </el-dialog> </template> <script lang="ts" setup> import { ref,reactive,getCurrentInstance,toRefs } from 'vue' import { Delete, Plus, ZoomIn } from '@element-plus/icons-vue' import type { UploadFile } from 'element-plus' //请求axios const currentInstance = getCurrentInstance(); const { $axios } = currentInstance.appContext.config.globalProperties; const { proxy } = currentInstance; const uploadDisabled = ref(false) const fileListCopy = reactive({ data: [] }); const dialogImageUrl = ref('') const dialogVisible = ref(false) const disabled = ref(false) //移除 const handleRemove = (file,fileList) => { console.log(file) fileListCopy.data = fileListCopy.data.filter(v => v.uid !== file.uid); uploadDisabled.value = false; } //查看 const handlePreview = (file: UploadFile) => { dialogImageUrl.value = file.url! dialogVisible.value = true } //点击上传 const handleUpload = (file,fileList) =>{ console.log(fileList.length) if(fileList.length>=1){ uploadDisabled.value = true; } } //父组件文件标识 const props = defineProps({ uploadFlag: String, }) const {uploadFlag} =toRefs(props) const emit = defineEmits(['callBack']) const upload = (file)=>{ let formData = new FormData(); formData.append('uploadFile', file.file); $axios.post( "upload/file", formData ).then((res)=>{ //上传结果回调 emit('callBack', {flag:uploadFlag.value,url:res.data}) }).catch(err=>{ proxy.$message.error(err.message) }) } </script> <style> .disabled .el-upload--picture-card { display: none!important; } img{ width: 100%; } </style> 二、图片查看组件 ViewPhoto.vue: <template> <el-dialog v-model="dialogVisible" :title="viewTitle"> <img w-full :src="dialogImageUrl" alt="Preview Image" @error="getErrorImage($event)"/> </el-dialog> </template> <script setup> import defaultImage from "@/components/files/errorImage.png" import {getCurrentInstance, toRefs,ref,onMounted} from "vue"; import { ElMessage } from "element-plus"; const currentInstance = getCurrentInstance(); const { $axios } = currentInstance.appContext.config.globalProperties; const dialogImageUrl = ref('') const dialogVisible = ref(false) const viewTitle = ref("") //父组件获取url const props = defineProps({ url: String, title:String }) const {url,title} =toRefs(props) //获取图片的完整地址 const getPreviewUrl = () => { $axios.get( "photo/preview",{fileName:url.value} ).then((res)=>{ viewTitle.value = title.value dialogImageUrl.value = res.data dialogVisible.value = true }).catch(err=>{ if(err.message == undefined){ ElMessage.error("获取文件阅览地址异常,请联系管理员") } ElMessage.error(err.message) }) } onMounted(()=>{ getPreviewUrl(); }) //异常处理 const getErrorImage = (e)=>{ e.target.src = defaultImage } </script> <style scoped> img{ width: 100%; height: 100%; } </style> 三、组件运用 <template> <el-row> <div style="width:100%" class="fileup" size="large">上传照片</div> <el-form-item style="margin-top: 10px;" v-model="userInfo.header" label="头像" size="large"> <!--文件上传组件--> <uc-upload-file :uploadFlag="headPicture" @callBack="getUploadRes"></uc-upload-file> </el-form-item> <!--文件查看,异步加载文件查看组件--> <el-form-item label="头像" @click="viewPhoto(userDetailInfo.avatar,'查看头像')" size="large"> <el-input v-model="userInfo.avatar" :disabled='true' title="点击查看" size="large" /> </el-form-item> </el-row> </template> <script setup> import {ref} from 'vue'; import { ElMessage } from "element-plus"; //上传图片 //标识:hp-头像 const headPicture = ref("hp") //上传结果 const getUploadRes = (res) => { if(res.flag == headPicture.value){ userInfo.header = res.url return; } userInfo.image = res.url }
//查看图片 const photoUrl = ref("") const viewTitle = ref("") const viewPhotoComponent = shallowRef(null); const viewPhoto = (url,title)=>{ if(url == undefined){ ElMessage.warning("请先上传"+title) return } photoUrl.value = url viewTitle.value = title //异步加载查看图片组件 viewPhotoComponent.value = defineAsyncComponent( () => import("@/components/files/ViewPhoto.vue") ); }