Vue @submit From表单提交
初学vue,from表单的操作官方提供了v-model双向绑定,这个功能强大,在data中列出所有表单字段,提交表单时我们只需用this.field就可以获取到表单中所有的数据。看似方便,但是日常开发中,data中双向绑定的字段并不是都需要做特殊处理,而其他字段就显得孤独和冗余。以下代码来自日常项目(较多,懒得删减,需要可以直接复制组成页面看效果),其中使用的部分组件来自第三方组件库vant,安装
初学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);
},
更多推荐
所有评论(0)