ElementUi文件上传组件、查看图片组件封装及运用

该文章展示了如何在Vue应用中使用ElementPlus库创建一个文件上传组件,支持拖拽上传、限制上传数量、预览图片及删除功能。同时,文章还包含了图片查看组件,用于展示已上传图片的详细视图。整个流程涉及axios进行后端API交互。
摘要由CSDN通过智能技术生成
一、文件上传组件
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")
  );
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值