vue3中上传组件upload简单使用

vue3中上传组件upload简单使用1 upload 组件上传 主页面 template el col span 24 el form item label 个人风采 prop avatar el form item el col template

大家好,我是讯享网,很高兴认识大家。

1、upload组件上传

主页面

<template> <el-col :span="24"> <el-form-item label="个人风采" prop="avatar"> <imageCut v-model="serviceForm.avatar" :fixedNumber="[86, 114]" :disabled="disabled1" > </imageCut> </el-form-item> <el-form-item label="姓名" prop="name"> <el-input v-model="serviceForm.name" :disabled="disabled1" /> </el-form-item> <el-form-item label="职称" prop="jobTitle"> <el-input v-model="serviceForm.jobTitle" :disabled="disabled1" /> </el-form-item> </el-col> </template> <script setup> import imageCut from "@/components/imageCutUpload/index"; </script>

讯享网

2、组件主要逻辑页面(components/imageCutUpload/index.vue)


讯享网

讯享网<template> <div class="component-upload-image"> <el-upload ref="imageUpload" :disabled="disabled" action="" list-type="picture-card" :auto-upload="false" :show-file-list="show" :file-list="fileList" :before-remove="handleDelete" :class="{ hide: fileList.length >= limit }" :on-change="handleChangeUpload" :on-preview="handlePictureCardPreview" :on-success="handleSuccess" > <el-icon class="avatar-uploader-icon"> <plus /> </el-icon> </el-upload> <!-- 上传提示 --> <div class="el-upload__tip"> 请上传 <template v-if="fileType"> 格式为 <b style="color: #f56c6c">{ 
  
    
  { fileType.join("/") }}</b> </template> 的文件 </div> <el-dialog v-model="showCropper" title="图片裁剪预览" width="800px" align-center append-to-body destory-on-close > <div class="box"> <div class="left"> <VueCropper v-if="showCropper" ref="cropper" :img="option.img" :outputSize="option.outputSize" :outputType="option.outputType" :info="option.info" :full="option.full" :canMove="option.canMove" :canMoveBox="option.canMoveBox" :original="option.original" :autoCrop="option.autoCrop" :fixed="option.fixed" :fixedNumber="option.fixedNumber" :centerBox="option.centerBox" :infoTrue="option.infoTrue" :fixedBox="option.fixedBox" :high="option.high" :mode="option.mode" @realTime="realTime" > </VueCropper> </div> <div class="right"> <h1 class="imgshow">图片展示</h1> <img :src="previewImg" alt="" class="previewImg" /> </div> </div> <template #footer> <div class="dialog-footer"> <el-button type="primary" @click="uploadImg">确 定</el-button> <el-button @click="cancel">取 消</el-button> </div> </template> </el-dialog> <el-dialog v-model="dialogVisible" title="预览" align-center width="800px" append-to-body > <img :src="dialogImageUrl" style="display: block; max-width: 100%; margin: 0 auto" /> </el-dialog> </div> </template> <script setup> import "vue-cropper/dist/index.css"; //引入裁剪 import { VueCropper } from "vue-cropper"; import { uploadImages,getstorage } from "@/api/common"; const props = defineProps({ modelValue: [String, Object, Array], // 图片数量限制 limit: { type: Number, default: 1, }, // 大小限制(MB) fileSize: { type: Number, default: 5, }, fileType: { type: Array, default: () => ["png", "jpg", "jpeg"], }, // 是否显示提示 isShowTip: { type: Boolean, default: true, }, //是否禁用 disabled: { type: Boolean, default: false, }, fixedNumber: { type: Array, default: [1, 1], }, contentType: { type: String, default: "RoleCert", }, }); const { proxy } = getCurrentInstance(); const emit = defineEmits(); const number = ref(0); const show = ref(false); const uploadList = ref([]); const dialogImageUrl = ref(""); const dialogVisible = ref(false); const baseUrl = import.meta.env.VITE_APP_BASE_URL; const fileList = ref([]); // const multipartFile = ref(); const showTip = computed( () => props.isShowTip && (props.fileType || props.fileSize) ); const option = ref({ //裁剪參數 img: "", outputSize: 1, info: false, // 裁剪框的大小信息 outputType: "jpg", // 裁剪生成图片的格式 canScale: false, // 图片是否允许滚轮缩放 autoCrop: true, // 是否默认生成截图框 // high: true, // 是否按照设备的dpr 输出等比例图片 fixedBox: true, // 固定截图框大小 不允许改变 fixed: true, // 是否开启截图框宽高固定比例 fixedNumber: props.fixedNumber, // 截图框的宽高比例 full: true, // 是否输出原图比例的截图 canMoveBox: true, // 截图框能否拖动 original: false, // 上传图片按照原始比例渲染 centerBox: false, // 截图框是否被限制在图片里面 infoTrue: true, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高 mode: "100% auto", // 图片默认渲染方式 }); const showCropper = ref(false); const previewImg = ref(""); const cropper = ref(null); const uid = ref(""); const filename = ref(""); const file = ref(undefined); watch( () => props.modelValue, (val) => { if (val) { show.value = true; // 首先将值转为数组 const list = Array.isArray(val) ? val : props.modelValue.split(","); // 然后将数组转为对象数组 fileList.value = list.map((item, index) => { if (typeof item === "string") { item = { name: "img" + index, url: item }; } return item; }); } else { show.value = false; fileList.value = []; return []; } }, { deep: true, immediate: true } ); function handleChangeUpload(file, fileList) { console.log("上传进来了") let isImg = false; if (fileList.length > props.limit) { show.value = false; } uid.value = file.raw.uid; filename.value = file.raw.name; if (props.fileType.length) { let fileExtension = ""; if (file.raw.name.lastIndexOf(".") > -1) { fileExtension = file.raw.name.slice(file.raw.name.lastIndexOf(".") + 1); } isImg = props.fileType.some((type) => { if (file.raw.type.indexOf(type) > -1) return true; if (fileExtension && fileExtension.indexOf(type) > -1) return true; return false; }); } else { isImg = file.raw.type.indexOf("image") > -1; } if (!isImg) { proxy.$modal.msgError( `文件格式不正确, 请上传${props.fileType.join("/")}图片格式文件!` ); return false; } // nextTick(() => { var reader = new FileReader(); reader.readAsDataURL(file.raw); reader.onload = (e) => { option.value.img = e.target.result; showCropper.value = true; }; // }); } function handleSuccess(file) { console.log(file) console.log("成功"); } // 删除图片 function handleDelete(file) { const findex = fileList.value.map((f) => f.name).indexOf(file.name); if (findex > -1 && uploadList.value.length === number.value) { fileList.value.splice(findex, 1); emit("update:modelValue", listToString(fileList.value)); return false; } } function cancel() { showCropper.value = false; } // 预览 function handlePictureCardPreview(file) { dialogImageUrl.value = file.url; dialogVisible.value = true; } // 对象转成指定字符串分隔 function listToString(list, separator) { let strs = ""; separator = separator || ","; for (let i in list) { if (undefined !== list[i].url && list[i].url.indexOf("blob:") !== 0) { strs += list[i].url.replace(baseUrl, "") + separator; } } return strs != "" ? strs.substr(0, strs.length - 1) : ""; } function blobToDataURI(blob, callback) { var reader = new FileReader(); reader.readAsDataURL(blob); reader.onload = function (e) { callback(e.target.result); }; } //获取裁剪图片 function realTime(data) { cropper.value.getCropBlob((data) => { // , { // uid: uid.value, // type: "image/png", // lastModified: Date.now(), // } file.value = new File([data], filename.value, { uid: uid.value, type: "image/png", lastModified: Date.now(), }); blobToDataURI(data, function (res) { previewImg.value = res; }); }); } //uploadImg function uploadImg() { proxy.$modal.loading("正在上传图片,请稍候..."); number.value++; let formData = new FormData(); formData.append("contentType", props.contentType); formData.append("fileType", 2); formData.append("file", file.value); // data = qs.stringify(data); uploadImages(formData) .then((res) => { if (res) { proxy.$modal.closeLoading(); show.value = true; showCropper.value = false; //uploadedSuccessfully(); getstorage(props.contentType).then((res2)=>{ //baseUrl=res2; //baseUrl=baseUrl.replace(props.contentType, ""); res2=res2.replace(props.contentType, ""); console.log(baseUrl); uploadList.value.push({ name: "expert", url: res2+res });//提交拼接下完整url uploadedSuccessfully(); }); } else { number.value--; proxy.$modal.closeLoading(); showCropper.value = false; proxy.$modal.msgError("上传图片失败"); proxy.$refs.imageUpload.handleRemove(file.value); uploadedSuccessfully(); } }) .catch(() => { number.value--; proxy.$modal.closeLoading(); showCropper.value = false; proxy.$modal.msgError("上传图片失败"); proxy.$refs.imageUpload.handleRemove(file.value); uploadedSuccessfully(); }) .finally(() => { // previewImg.value = "1"; }); } // 上传结束处理 function uploadedSuccessfully() { if (number.value > 0 && uploadList.value.length === number.value) { fileList.value = fileList.value .filter((f) => f.url !== undefined) .concat(uploadList.value); uploadList.value = []; number.value = 0; emit("update:modelValue", listToString(fileList.value)); } } </script> <style scoped lang="scss"> .previewImg { width: 100%; } // .el-upload--picture-card 控制加号部分 :deep(.hide .el-upload--picture-card) { display: none; } .box { width: 100%; height: 500px; display: flex; .left { width: 68%; } .right { flex: 1; padding-left: 20px; .imgshow { line-height: var(--el-dialog-font-line-height); font-size: var(--el-dialog-title-font-size); color: var(--el-text-color-primary); } } } </style> 

3、接口文件代码(common.js)

import request from "@/utils/request"; export function uploadImages(data) { return request({ url: "/api/base/storage/upload", method: "post", headers: { "Content-Type": "multipart/form-data" }, data, isGreen:true }); }

注意,以下代码是由于后端接口返回的图片路径是不完整的,所以又简单调用了个接口才拼接成完整的路径,若返回的是完整的则不需要此处代码,只要uploadedSuccessfully();

getstorage(props.contentType).then((res2)=>{
          //baseUrl=res2;
          //baseUrl=baseUrl.replace(props.contentType, "");
          res2=res2.replace(props.contentType, "");
          console.log(baseUrl);
          uploadList.value.push({ name: "expert", url: res2+res });//提交拼接下完整url
          uploadedSuccessfully();
        });

小讯
上一篇 2025-04-03 07:01
下一篇 2025-03-28 15:03

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/122259.html