uniapp实现表单提交带图片上传 在做表单提交的时候,我们可能面临有图片上传,放在原生的html就好解决,form标签加上

enctype=“multipart/form-data”
uniapp微信小程序
1.原图
在这里插入图片描述
在这里插入图片描述
页面部分

<form :model="data" @submit="submit" @reset="">
		<view class="top bgbai u-m-t-30" :class="{disabled: !isaction && data.renz.id}">
				<view class="u-flex item">
					<view class="left required">公司全称</view>
					<input type="text" placeholder-class="line" v-model="data.renz.name" placeholder="请填写公司全称" />
				</view>
				<view class="u-flex item">
					<view class="left required">纳税人识别号</view>
					<input type="number" maxlength="20" placeholder-class="line" v-model="data.renz.ident" placeholder="请填写纳税人识别号" />
				</view>
				<view class="u-flex item">
					<view class="left required">公司地址</view>
					<input type="text" class="u-flex-1" v-model="data.renz.code1" placeholder-class="line" placeholder="请填写公司地址" />
				</view>
				<view class="u-flex item">
					<view class="left required">公司电话</view>
					<input type="text" placeholder-class="line" v-model="data.renz.phone" placeholder="请填写公司电话" />
				</view>
				<view class="u-flex item">
					<view class="left required">开户行</view>
					<input type="text" placeholder-class="line" v-model="data.renz.khyh" placeholder="请填写开户行" />
				</view>
				<view class="u-flex item">
					<view class="left required">开户行账户</view>
					<input type="text" placeholder-class="line" v-model="data.renz.khhuser" placeholder="请填写开户行账户" />
				</view> 
				<view class="item permit u-flex-col">
					<view class="left u-m-b-15 required">营业执照:</view>
					<view>
						<view class="yingyezhizhao" @click="zhizhaoFile">
							<image :src="tempAvatar ? tempAvatar : Img" mode="aspectFit"></image>
							<view class="mycolse" v-show="isdel" @click.stop="removeTemp">
								<u-icon name="close-circle-fill" size="46" color="#000000"></u-icon>
							</view>
						</view>
					</view>
				</view>
				<view class="filetip xsize">
					只支持中国大陆工商局或市场监督管理局颁发的工商营业执照,且必须在有效期内, 请格式要求:原件照片,扫描件或者加盖公章的复印件,支持.jpg.jpeg.gif.png 格式照片大小不超过2M上传最新的营业执照。
				</view>
				<view class="u-flex-col item permit">
					<view class="left u-m-b-15">经营范围:</view>
					<textarea 
					 class="fwtextarea"
					 v-model="data.renz.fanwei"
					 placeholder="一般经营范围"
					 placeholder-class="line" 
					 maxlength="200"
					 />
				</view>
				<view class="checkAddress between u-font-28 u-m-t-30" @click="setmrAddress">
					<text class="checkTxt">是否与默认收货地址一致</text>
					<text class="goTo">点击前往>></text>
				</view>
				<view class="bgbai drawer" :class="{disabled: !isaction && data.renz.id}">
			<view class="u-flex item">
				<view class="left required">收票人姓名</view>
				<input type="text" placeholder-class="line" v-model="data.userc.shname" placeholder="请填写收票人姓名" />
			</view>
			<view class="u-flex item">
				<view class="left required">收票人手机</view>
				<input type="text" placeholder-class="line" v-model="data.userc.tel" placeholder="请填写收票人手机" />
			</view>
			<view class="u-flex item" @tap="showgcsPicker">
				<view class="left required">收票人省份</view>
				<input type="text" placeholder-class="line" v-model="data.userc.provice" disabled class="u-flex-1" placeholder="选择省/市/区" />
				<text class="mix-icon icon-you"></text>
			</view>
			<view class="u-flex item">
				<view class="left required">详细地址</view>
				<input type="text" placeholder-class="line" v-model="data.userc.address" placeholder="街道、楼牌号等" />
			</view>
			<view class="btn-wrap center u-flex-col u-m-t-50" v-show="!data.renz.id || isaction">
				<u-button class="btn center" :custom-style="btnSytle" hover-class="none" shape="circle" @click="submit">提交</u-button>
			</view>
			</view>
	</form>

js部分

<script>
import {checkStr, checkAddressCode, orgcodevalidate} from '@/common/js/util'
export default {
   data(){
   		return {
   			data: {
   				renz: {
   					name: '',
   					ident: '',
   					code1: '',
   					phone: '',
   					khyh: '',
   					khhuser: '',
   					fanwei: ''
   				},
   				userc: {
   					shname: '',
   					tel: '',
   					provice: '',
   					address: ''
   				}
   			},
   			show: false,
   			imgaction: 'index.php?m=Wxapi&c=User&a=engineer',
   			CDN: this.CDN,
   			stateArr:['审核中','审核完成','工程商认证审核未通过'],
   			colorArr:['#ff0000','#08bb71','#999999'],
   			isaction: false,
   			isdel: false,
   			btnSytle: {
   				width: '100%',
   				height: '80rpx',
   				fontSize: '32rpx',
   				borderRadius: '40rpx',
   				color: '#fff',
   				backgroundColor: 'transparent',
   				backgroundImage: 'linear-gradient(to left, rgb(250, 176, 34) ,#f83600)'
   			},
   			tempAvatar: '',
   			Img: '/static/icon/cream.png',
   			filesize: 0,
   			isModel: false  //是否显示模态框
   		}
   	},
   	methods: {
   	// 上传营业执照
   		zhizhaoFile(){
   			let that = this;
   			uni.chooseImage({
   				count: 1,
   				sizeType: 'original',  //指定原图
   				success: res=> {
   					that.filesize = res.tempFiles[0].size/1024/1024;  //转换MB
   					if(that.filesize > 1){
   						that.$util.msg('上传文件大小不能超过1MB');
   						return;
   					}
   					that.tempAvatar = res.tempFilePaths[0];
   				},
   				error: err=>{
   					console.log(err)
   				}
   			})
   		},
   		// 提交认证
   		submit(){
   			const userid = uni.getStorageSync('uniIdToken') || 0;
   			if(userid <= 0){
   				this.$util.msg('请先登录!');
   				return;
   			}
   			const datas = this.data.renz;
   			const userdata = this.data.userc;
   			if(!datas.name){
   				this.$util.msg('请输入公司全称');
   				return;
   			}
   			if(datas.ident){
   				if(!checkStr(datas.ident, 'zzsnsno')){
   					this.$util.msg('纳税人识别号位数限制为15、18、20位,请检查');
   					return;
   				}else{
   					let addressCode = datas.ident.substring(0,6);
   					let ischeck = checkAddressCode(addressCode);
   					if(!ischeck){
   						this.$util.msg('请输入正确的纳税人识别号 (地址码)');
   						return;
   					}else{
   						// 校验组织机构代码
   						let orgCode = datas.ident.substring(6, 9);
   						let istrue = orgcodevalidate(orgCode);
   						if(!istrue){
   							this.$util.msg('请输入正确的纳税人识别号 (组织机构代码)');
   							return;
   						}
   					}
   				}
   			}else{
   				this.$util.msg('请输入纳税人识别号');
   				return;
   			}
   			if(!datas.code1){
   				this.$util.msg('请输入公司地址');
   				return;
   			}
   			if(!datas.phone){
   				this.$util.msg('请输入公司电话');
   				return;
   			}
   			if(datas.khyh){
   				if(!checkStr(datas.khyh, 'chinese')){
   					this.$util.msg('开户行须为中文');
   					return;
   				}
   			}else{
   				this.$util.msg('请输入开户行');
   				return;
   			}
   			if(datas.khhuser){
   				if(!checkStr(datas.khhuser, 'number')){
   					this.$util.msg('开户行账户格式错误');
   					return;
   				}
   			}else{
   				this.$util.msg('请输入开户行账户');
   				return;
   			}
   			if(this.tempAvatar){
   				if(this.filesize > 1){
   					this.$util.msg('上传文件大小不能超过1MB');
   					return;
   				}
   			}else{
   				this.$util.msg('请上传营业执照');
   				return;
   			}
   			if(!userdata.shname){
   				this.$util.msg('请输入收票人姓名');
   				return;
   			}
   			if(userdata.tel){
   				if(!checkStr(userdata.tel, 'mobile')){
   					this.$util.msg('手机号码格式错误');
   					return;
   				}
   			}else{
   				this.$util.msg('请输入收票人手机号码');
   				return;
   			}
   			if(!userdata.provice){
   				this.$util.msg('请选择地区');
   				return;
   			}
   			if(!userdata.address){
   				this.$util.msg('请输入详细地址');
   				return;
   			}
   			var obj = Object.assign(datas,userdata);
   			obj = JSON.parse(JSON.stringify(obj));
   			obj.uid = userid;
   			// obj.shname = userdata.name;
   			uni.showLoading({
   				title: '提交中...',
   				mask: true
   			})
   			if(this.tempAvatar === this.CDN + this.data.renz.pic1){
   				// 旧图片未修改
   				this.oldUpload(obj);
   			}else{
   				// 重新上传图片
   				this.yesUpload(obj);
   			}
   		},
   		// 旧图片未改调用
   		async oldUpload(data){
   			const res = await this.$request.post(this.imgaction,data);
   			if(res.status === 200){
   				uni.hideLoading();
   				this.$util.msg(res.msg);
   				this.isaction = this.isdel = false;
   				if(res.data.renz){
   					this.data.renz = res.data.renz;
   					this.data.renz.khyh = res.hang;
   					this.data.renz.khhuser = res.hangzh;
   				}
   				if(res.data.userc){
   					this.data.userc = res.data.userc;
   					this.data.userc.shname = res.data.userc.name;
   					delete res.data.userc.name;
   				}
   			}else{
   				uni.hideLoading();
   				this.$util.msg(res.msg);
   				return;
   			}
   		},
   		//重新上传图片调此方法
   		yesUpload(data){
   			uni.uploadFile({
   				url: this.CDN + this.imgaction,
   				filePath: this.tempAvatar,
   				name: 'pic1',
   				formData: data,  //顺带整个表单对象传给服务端
   				success: (res) => {
   					const resultData = JSON.parse(res.data)
   					if(resultData.status === 200){
   						uni.hideLoading();
   						this.$util.msg(resultData.msg);
   						this.isaction = this.isdel = false;
   						if(resultData.data.renz){
   							this.data.renz = resultData.data.renz;
   							this.data.renz.khyh = resultData.hang;
   							this.data.renz.khhuser = resultData.hangzh;
   						}
   						if(resultData.data.userc){
   							this.data.userc = resultData.data.userc;
   							this.data.userc.shname = resultData.data.userc.name;
   							delete resultData.data.userc.name;
   						}
   					}else{
   						uni.hideLoading();
   						this.$util.msg(resultData.msg);
   						return;
   					}
   				}
   			})
   		}
   	}
}

后端
在这里插入图片描述

    /**
     * 单文件上传(微信小程序只支持单文件上传)
     *
     * @param file
     * @return
     * @throws Exception
     */
    @PostMapping("/filesUpload")
    public R uploadFile(FormDataReq f, @RequestParam("file") MultipartFile file, @RequestParam(name = "businessType", required = true) String businessType) {
        return R.ok("文件上传成功!", fileService.uploadPic(file, businessType));
    }

子组件

<!-- 上传图片 -->
<template>
	<view class='m-upload'>
		<view class="label">
			<text>{{label}}</text>
		</view>
		<view class="image">
			<view class="image-list" v-for="item in imageList" :key="item.id">
				<image v-if="!previewFlag" class="delete" src="/static/upload/delete.png" @click="tapDelete(item.id)">
				</image>
				<image class="image-data" :src="item.path" mode="aspectFill" @click="tapPreview(item.path)"></image>
			</view>
			<image v-if="!previewFlag" class="upload-btn-icon" src="/static/upload/upload.png"
				@click="tapUpload(businessType)"></image>

			<!-- 确定上传到服务器 -->
			<button type="primary" @click="submitImg(businessType)">{{businessType}}</button>
		</view>
	</view>
</template>

<script>
	export default {
		props: {
			label: {
				type: String,
				default: '上传图片'
			},
			businessType: {
				type: String,
				default: '01' //业务类型 01-考勤打卡 02-审批 03-到点留痕
			},
			previewFlag: {
				type: Boolean,
				default: false //预览模式不显示删除图标和上传图标
			},
			//初始显示数据
			initlist: {
				type: Array,
				default: function() {
					return [];
				}
			}
		},
		data() {
			return {
				imgNum: 0, //一共选中了多少张照片,用来限制本次最大上传数量
				imageList: [],
				serverUrl: "http://127.0.0.1:8080/file/filesUpload?businessType=", //要上传的图片的服务器地址
			}
		},
		created() {

		},
		//页面渲染完成
		mounted() {
			for (let item of this.initlist) {
				let obj = {
					...item,
				}
				this.imageList.push(obj);
			}
		},
		watch: {
			initlist(nVal, oVal) {
				for (let item of nVal) {
					let obj = {
						...item,
					}
					this.imageList.push(obj);
				}

			},
		},
		/**
		 * 计算属性
		 */
		computed: {

		},
		methods: {
			tapDelete(id) {
				let that = this;
				//console.log(`删除${id}`);
				//先移除显示的图片,在删除服务器端的图片
				let images = that.imageList;
				let indexImage = images.findIndex(n => n.id == id);
				if (indexImage != -1) {
					that.imageList.splice(indexImage, 1); //删除当前数组对象

					//调用接口,删除图片
					console.log('删除图片', id);
					that.$emit('myEvent', that.imageList)
				}
			},
			tapPreview(path) {
				console.log(`当前图片${path}`);
				let images = [];
				for (let item of this.imageList) {
					images.push(item.path);
				}
				// 预览图片
				uni.previewImage({
					current: path,
					urls: images,
					indicator: 'default',
					loop: true,
				});

			},

			tapUpload() {
				let that = this;

				uni.chooseMessageFile({
					count: 9, //默认9
					sizeType: ['compressed'], //可以指定是原图还是压缩图,默认二者都有
					success: function(res) {
						// 遍历要上传的图片临时地址,进行上传
						for (let item of res.tempFiles) {

							that.imageList.push({
								path: item.path,
							})



							// 判断本次最多上传多少照片
							that.imgNum++;
							if (that.imgNum > 9) {
								that.imgNum = 9;
								uni.showToast({
									icon: "none",
									title: "上传的图片最多不能超过9张",
								});
								return;
							}

							console.log("that.imageList", that.imageList)
							that.$emit('myEvent', that.imageList)
						}
					}
				});
			},

			// 确定上传图片,传到服务器
			submitImg(businessType) {
				console.log("businessType->", businessType)
				let that = this;
				// let token = uni.getStorageSync(TOKEN_KEY) || ''

				let token =
					"eyJhbGciOiJIUzI1NiJ9.eyJtYW5nZUNvbSI6Ijg2MjEiLCJyb2xlS2V5IjoibnFyb2xlIiwiY29tQ29kZSI6Ijg2MjEwMDAwMDAwMDAwMDAxIiwidXNlcklkIjoiemhhbmdzYW4iLCJpYXQiOjE2NTI1MzAyMjIsImV4cCI6MTY1MzczOTgyMn0.F-L-r2f4PkmgBaKkRp1GSo6Jerp-oHDpCr2HI4bdJ-M";
				// 遍历要上传的图片临时地址,进行上传
				that.imageList.map((val) => {
					console.log("val-》", val)
					uni.uploadFile({
						url: that.serverUrl + businessType, //服务器地址
						filePath: val.path, //存在本地要上传的临时图片地址
						name: "file", //名字可以随便写
						header: {
							Authorization: "Bearer " + token,
							"Content-Type": "multipart/form-data",
						},
						formData: {
							execId: "execId",
							record: "record2",
							num: "num3",
						},
						success(res) {

							//上传成功的回调函数
							console.log(res, "上传成功");
							uni.showToast({
								icon: "none",
								title: "上传成功",
							});

						},
						fail(res) {
							console.log(res, "上传失败");
							// that.imageList.splice(indexImage, 1); //删除当前数组对象
							uni.showToast({
								icon: "none",
								title: "上传失败",
							});
						},

					});

				});
			},

		}
	}
</script>

<style lang="scss" scoped>
	.m-upload {

		.label {
			padding: 20rpx;
			background-color: #eeeeee;
			font-size: 28rpx;
			font-weight: bold;
			color: #303133;
		}

		.image {
			display: flex;
			flex-wrap: wrap;
			background-color: #FFFFFF;
			padding: 20rpx;

			.image-list {
				position: relative;

				.delete {
					position: absolute;
					z-index: 10;
					width: 40rpx;
					height: 40rpx;
					top: 0;
					right: 0;
				}

				.image-data {
					width: 216rpx;
					height: 216rpx;
					padding: 10rpx 10rpx 0 10rpx;
				}

				// .upload-progress {
				// 	width: 176rpx;
				// 	padding: 0 10rpx;
				// 	position: absolute;
				// 	z-index: 20;
				// 	height: 20rpx;
				// 	left: 20rpx;
				// 	bottom: 140rpx;
				// }

				// .upload-mask {
				// 	position: absolute;
				// 	z-index: 19;
				// 	width: 216rpx;
				// 	height: 216rpx;
				// 	top: 10rpx;
				// 	left: 10rpx;
				// 	background-color: #000000;
				// 	opacity: 0.6;
				// }
			}

			.upload-btn-icon {
				width: 216rpx;
				height: 216rpx;
				padding: 10rpx 10rpx 0 10rpx;
			}
		}
	}
</style>

父组件

<template>
	<view class="page">
		<m-file-upload @myEvent="getMsg" :label="label" :previewFlag="previewFlag" :initlist="list"
			:businessType="businessType"></m-file-upload>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				previewFlag: false, //是否属于预览模式 true-预览模式 false-上传模式
				label: '上传图片',
				businessType: '02', //业务类型 01-考勤打卡 02-审批 03-到点留痕
				list: [{
						id: 1,
						path: 'http://localhost:8080/f/20220514154136.png',
						businessType: '01' //业务类型 01-考勤打卡 02-审批 03-到点留痕
					},
					{
						id: 2,
						path: 'http://localhost:8080/f/20220514154235.png',
						businessType: '02' //业务类型 01-考勤打卡 02-审批 03-到点留痕
					},
					{
						id: 3,
						path: 'http://localhost:8080/f/20220514154638.png',
						businessType: '03' //业务类型 01-考勤打卡 02-审批 03-到点留痕
					}
				],
			}
		},
		onLoad() {

		},
		methods: {
			getMsg(res) {
				console.log("res",res)
			}
		}
	}
</script>

<style scoped>

</style>

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
uniapp中,可以使用原生的`<form>`标签提交表单数据。在提交之前,可以通过`<input>`等表单元素的`v-model`指令来获取用户输入的数据,并进行数据格式验证。 下面是一个简单的例子,展示了如何使用`<form>`标签和`<input>`元素来提交表单数据,并使用`v-model`指令获取和验证数据: ```html <template> <form @submit.prevent="submitForm"> <div> <label for="name">Name:</label> <input id="name" type="text" v-model.trim="name" required> <span v-if="nameError" class="error">{{ nameError }}</span> </div> <div> <label for="email">Email:</label> <input id="email" type="email" v-model.trim="email" required> <span v-if="emailError" class="error">{{ emailError }}</span> </div> <button type="submit">Submit</button> </form> </template> <script> export default { data() { return { name: '', email: '', nameError: '', emailError: '' } }, methods: { submitForm() { // 进行数据格式验证 if (!this.name) { this.nameError = 'Name is required' return } if (!this.email) { this.emailError = 'Email is required' return } if (!this.isValidEmail(this.email)) { this.emailError = 'Email is invalid' return } // 提交表单数据 const formData = { name: this.name, email: this.email } console.log(formData) }, isValidEmail(email) { // 验证邮箱格式 // ... return true } } } </script> <style> .error { color: red; } </style> ``` 在上面的例子中,`<input>`元素的`v-model`指令绑定了`name`和`email`两个数据属性,当用户输入时,这两个属性的值会自动更新。当用户点击提交按钮时,`submitForm`方法会被调用。在该方法中,先进行数据格式验证,如果发现数据有误,则会在页面上显示错误信息;如果数据验证通过,则会将表单数据包装成一个对象,然后输出到控制台。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gblfy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值