vue3 基于element plus 二次封装上传图片组件

  • Post author:
  • Post category:vue

本次封装了 图片上传,回显,以及编辑功能完善
话不多说上代码,代码里的注释仔细看哦,说明在里面

<template>
	<el-upload v-model:file-list="fileList" :list-type="listType" class="avatar-uploader" :action="fileUploadUrl"
		:on-success="handleAvatarSuccess" :on-remove="handleRemove" :before-upload="beforeAvatarUpload"
		  :accept="accept" :limit="limit" :on-exceed="handleExceed">
		<el-icon>
			<Plus />
		</el-icon>
	</el-upload>
</template>
<script lang="ts" setup>
	import {
		ref,
		reactive,
		watch
	} from "vue";
	import {
		useRouter,
		useRoute
	} from "vue-router";
	import {
		useStore
	} from "vuex";
	import {
		ElMessage
	} from "element-plus";

	const router = useRouter();
	const route = useRoute();
	const store = useStore();
	
	const fileList = reactive([]);
	const listType = ref("picture-card");
	const fileUploadUrl = import.meta.env.VITE_BASE_URL + "/files/files/uploadPart"; //上传得接口路径;可根据需求
	//属性
	const props = defineProps({
		imgUrl: "",
		limit:'',
		accept:'',
		mulTip: { type: Boolean, default: false }
	});
	setTimeout(() => {
		//文件回显,这里异步处理了,因为回显需要等待接口数据返回
		if (props.imgUrl) {
			let tmpArray=props.imgUrl.split(",");
			tmpArray.forEach(item => {
				fileList.push({
					name: item,
					url: item
				})
			});
		}
	}, 500);
	//解析组件传过来的方法
	const emits = defineEmits(["getUrl"]);
	
	//上传成功回调
	const handleAvatarSuccess=(res,file, uploadFiles) => {
		//临时路径
		let urls = [];
		//处理文件list
		uploadFiles.forEach(item => {
			// 上传文件是带有response属性的,回显的文件没有。处理是为了回显再编辑文件的时候
			if(item){
				let rs=item.response;
				if(rs){
					let code=rs.code;
					if(code==200){
						let fileUrl=rs.data.fileUrl;
						urls.push(fileUrl);
					}
				}else{
					urls.push(item.url);
				}
			}
		});
		//返回父组件 给到指定字段赋值,多文件以逗号分隔
		emits("getUrl", urls.toString());
	};
	//删除
	const handleRemove = (uploadFile, uploadFiles) => {
		//临时路径
		let urls = [];
		//处理文件list
		uploadFiles.forEach(item => {
			// console.log(el.response.fileUrl);
			if(item){
				let rs=item.response;
				if(rs){
					let code=rs.code;
					if(code==200){
						let fileUrl=rs.data.fileUrl;
						urls.push(fileUrl);
					}
				}else{
					urls.push(item.url);
				}
			}
		});
		//返回父组件 给到指定字段赋值,多文件以逗号分隔
		emits("getUrl", urls.toString());
	
	}
	//文件限制
	const handleExceed=(files, fileList)=> {
		ElMessage.warning(`当前限制选择 ${props.limit} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
	}
	//上传前的校验
	const beforeAvatarUpload = (rawFile) => {
		if (
			rawFile.type !== "image/jpeg" &&
			rawFile.type !== "image/png"
		) {
			ElMessage.error("只能上传jpg或png");
			return false;
		} else if (rawFile.size / 1024 / 1024 > 2) {
			ElMessage.error("文件大小不能超过2MB!");
			return false;
		}
		return true;
	};
	//const handleChangePic = () => {
		//if (props.mulTip) {
		//	if (fileList.value.length > 1) {
		//		fileList.value.splice(0, 1);
		//	}
		//}
	//}

</script>
<style lang="scss" scoped>
	.avatar {
		width: 100px;
		height: 80px;
	}
</style>

接下来就是使用(供参考)
传值多文件和回显都是以逗号分隔

<template>
//imgUrl 为绑定的字段   @getUrl方法为绑定的值 赋值  limit 为上传限制的个数    accept为上传限制格式
<Uploadimg
   :imgUrl="userAuthForm.service.idCardFront"
   @getUrl="getIdCardFrontUrl"
  :limit="1"
   accept=".png,.jpg"
  ></Uploadimg>
</template>
<script lang="ts" setup>
import Uploadimg from "@/components/upload/index.vue";
//上传参数
const userAuthForm = reactive({
service:{
idCardFront:""
}
})
// @getUrl方法
const getIdCardFrontUrl = (url) => {
  userAuthForm.service.idCardFront = url;
};
</script>

好了,至此结束,有问题欢迎留言交流


版权声明:本文为qq_48850466原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。