初学vue,from表单的操作官方提供了v-model双向绑定,这个功能强大,在data中列出所有表单字段,提交表单时我们只需用this.field就可以获取到表单中所有的数据。看似方便,但是日常开发中,data中双向绑定的字段并不是都需要做特殊处理,而其他字段就显得孤独和冗余。

以下代码来自日常项目(较多,懒得删减,需要可以直接复制组成页面看效果),其中使用的部分组件来自第三方组件库vant,安装命令:npm i vant -S
 from:

<template>
	<div class="home">
		<div class="register-from">
			<form @submit.prevent="saveApply">
				<ul class="register-info between">
					<li>
						<input type="text" name="name" placeholder="* 姓名" :value="field.name" />
					</li>
					<li>
						<input type="text" name="student_id" placeholder="* 学号" :value="field.student_id" />
					</li>
					<li>
						<input type="text" name="department" placeholder="学院" :value="field.department" />
					</li>
					<li>
						<input type="text" name="specialty" placeholder="专业" :value="field.specialty" />
					</li>
					<li>
						<input type="text" name="volunteer_number" placeholder="志愿者编号" :value="field.volunteer_number" />
					</li>
					<li>
						<input type="text" name="phone" placeholder="手机号码" :value="field.phone" />
					</li>
					<li>
						<input type="text" name="wechat" placeholder="微信" :value="field.wechat" />
					</li>
					<li>
						<input type="text" name="qq" placeholder="QQ" :value="field.qq" />
					</li>
				</ul>
				<div class="split">意向高中</div>
				<ul class="register-info between">
					<li>
						<input type="text" readonly name="province_city_name" placeholder="请选择省份城市" @click="show = true"
							v-model="field.province_city_name" />
					</li>
					<li>
						<input type="text" readonly name="school_name" placeholder="请选择高中" :value="field.school_name"
							@click="openSchoolSearch" />
					</li>
				</ul>
				<div class="split">活动方案</div>
				<ul class="register-info between">
					<li>
						<input type="text" name="activity_date" placeholder="活动时间" @click="dateShow = true" :value="field.activity_date">
					</li>
					<li>
						<input type="text" name="activity_human" placeholder="预计高中参与人数" :value="field.activity_human">
					</li>
					<li class="textarea">
						<textarea rows="" cols="" name="activity_modus" placeholder="活动形式">{{field.activity_modus}}</textarea>
					</li>
				</ul>
				<div class="split">中学联系方式</div>
				<ul class="register-info between">
					<li><input type="text" name="contact_phone" value="" placeholder="联系人姓名" :value="field.contact_phone"/></li>
					<li><input type="text" name="high_school_contact" value="" placeholder="联系方式" :value="field.high_school_contact"></li>
				</ul>

				<button type="submit" class="btn">确认提交</button>
			</form>
		</div>
		<!-- 三级联动选择 -->
		<Popup v-model="show" round position="bottom">
			<Cascader v-model="cascaderValue" title="请选择所在地区" :options="options" @close="show = false"
				@finish="onFinish" />
		</Popup>
		<!-- 高中学校筛选 -->
		<schoolSearch ref="schoolSearch" :selectedlist="schoolList" @getselectedsearch="selectedSchool($event)"
			@closet="closetWindow" v-show="schoolSearchShow"></schoolSearch>
		<!-- 日历选择 -->
		<Popup v-model="dateShow" round position="bottom">
			<DatetimePicker @confirm="datePicker" type="date" title="选择年月日" v-model="currentDate" :min-date="minDate"
				:max-date="maxDate" :formatter="formatter" />
		</Popup>
	</div>

</template>

javascript: (重点是methods中的 saveApply(e) 方法)

<script>
	import schoolSearch from '@/components/school-search/search'
	import {
		Cascader,
		Popup,
		Toast,
		DatetimePicker
	} from 'vant'
	import 'vant/lib/cascader/style'
	import 'vant/lib/popup/style'
	import 'vant/lib/toast/style'
	import 'vant/lib/datetime-picker/style'

	export default {
		name: 'Apply',
		components: {
			schoolSearch,
			Cascader,
			Popup,
			DatetimePicker
		},
		data() {
			return {
				field: {
					high_school_type: 3,
					is_principle: 2,
					school_name:'',
					province_city_name:'',
					activity_date:''
				},
				dateShow: false,
				currentDate: new Date(),
				minDate: new Date(),
				maxDate: new Date(2022, 6, 30),

				schoolSearchShow: false,
				schoolList: [],
				cascaderValue: '',
				show: false,
				options: [{
						text: '浙江省',
						value: '330000',
						children: [{
							text: '杭州市',
							value: '330100'
						}, {
							text: '宁波市',
							value: '1234'
						}],
					},
					{
						text: '江苏省',
						value: '320000',
						children: [{
							text: '南京市',
							value: '320100'
						}],
					},
				],

			}
		},
		computed: {
			
		},
		created() {

		},
		mounted() {

		},
		methods: {
			saveApply(e) {
				//如果需要从后端获取数据作为表单默认数据,假装obj是接口获取的数据
				let obj = {
					name:"wwc",
					student_id:"123456"
				};
				//Object.assign将数据与feild做动态绑定
				this.field = Object.assign({},this.field,obj);
				//以下为获取表单数据的重点
				//@submit触发后可以访问原始的 DOM 事件,在DOM中可以得到所有表单节点的所有属性和value
				var dataElement = e.srcElement;
				var value = {};
				for(let element of dataElement){
					value[element.name] = element.value
				}
				console.log(this.field);
			},

			checkedRedio(field, value) {
				this.field[field] = value;
			},

			openSchoolSearch() {
				if (this.field.province == "" || this.field.province == null) {
					console.log(this.field.province);
					Toast("请先选择省份城市");
					return false;
				}
				this.schoolSearchShow = true;
			},

			//学校检索组件回调
			selectedSchool(el) {
				this.field.high_school = el.name;
				this.schoolSelect = false;
			},

			closetWindow() {
				this.schoolSearchShow = false
			},

			datePicker(e) {
				console.log(e);
			},

			formatter(type, val) {
				if (type === "year") {
					return `${val}年`;
				} else if (type === 'month') {
					return `${val}月`;
				} else if (type === 'day') {
					return `${val}日`;
				}
				return val;
			},

			//日历
			onConfirm(date) {
				console.log(date);
			},

			//省市区
			onFinish({
				selectedOptions
			}) {
				this.show = false;
				this.field.province_city_name = selectedOptions.map((option) => option.text).join('/');
			}
		}
	}
</script>

css:

<style lang="scss" scoped>
	.top-pic {
		display: block;
		width: 4.76rem;
		margin: .78rem auto .78rem;
	}

	.register-from {
		width: 6.3rem;
		margin: 0 auto;
		margin-bottom: 2.5rem;
	}

	.register-info {
		width: 100%;
		flex-wrap: wrap;

		& li {
			margin-top: .35rem;
			width: 48%;
			height: .7rem;

			& input {
				width: 100%;
				height: 100%;
				border-bottom: .01rem #c0c0c0 solid;
				font-size: 0.32rem;
			}
		}
	}

	.split {
		margin-top: 0.89rem;
		color: #333;
	}

	.school-type,
	.principal-select {
		margin-top: 0.89rem;

		&:after {
			content: "";
			display: block;
			clear: both;
		}
	}

	.radio {
		float: right;
		width: 4.6rem;
	}

	.radio-item label {
		display: inline-block;
		position: relative;
		top: 0.04rem;
		width: 0.3rem;
		height: 0.3rem;
		margin-right: 0.12rem;
		background: url(http://image.360eol.com/nx_images/xcx/select.png) center center no-repeat;
		background-size: .3rem .3rem;
	}

	.radio .on label {
		background: url(http://image.360eol.com/nx_images/xcx/selected.png) center center no-repeat;
		background-size: .3rem .3rem;
	}

	.principal-radio {
		width: 1.8rem;
		margin-right: 1.4rem;
	}

	.register-info .textarea {
		width: 100%;
		height: auto;
	}

	.textarea textarea {
		height: 2.5rem;
		width: 6.08rem;
		border-radius: 0.08rem;
		padding: 0.1rem;
		border: 0.01rem solid #d8d8d8;
		font-size: 0.28rem;
	}

	.btn {
		position: fixed;
		left: 0;
		right: 0;
		bottom: 1rem;
		width: 6.58rem;
		height: 0.94rem;
		margin: 0 auto;
		margin-top: 0.3rem;
		background: linear-gradient(135deg, rgba(0, 191, 255, 1) 0%, rgba(3, 98, 198, 1) 100%);
		border: 0;
		border-radius: .47rem;
		line-height: .94rem;
		text-align: center;
		font-size: .38rem;
		color: #fff;
	}
</style>

重点:

            saveApply(e) {
                //如果需要从后端获取数据作为表单默认数据,假装obj是接口获取的数据
                let obj = {
                    name:"wwc",
                    student_id:"123456"
                };
                //Object.assign将数据与feild做动态绑定
                this.field = Object.assign({},this.field,obj);
                //以下为获取表单数据的重点
                //@submit触发后可以访问原始的 DOM 事件,在DOM中可以得到所有表单节点的所有属性和value
                var dataElement = e.srcElement;
                var value = {};
                for(let element of dataElement){
                    value[element.name] = element.value
                }
                console.log(this.field);
            },

Logo

前往低代码交流专区

更多推荐