2020.2.29
axios实现表单的验证提交
1、Demo描述:
1)登录:
-
检查学生号,密码是否为空。 思路:用vue的v-model实现数据的双向绑定
-
检查该用户是否存在。 思路: 用axios.get来实现异步查
2)注册:
-
检查学生号,用户名,邮箱,密码1,密码2是否为空或相等。 思路:用vue的v-model实现数据的双向绑定
-
检查学生号是否被注册过 思路:用axios.get来实现异步查询
备注:
1) 这里主要框架为springboot + thymeleaf + bootstrap + vue,重点问题落在用哪个异步框架? jquery? or axios?
2) 两个页面处理思路类似,先处理登录页面,再验证该方法在注册页面是否奏效
3)已知只有一条{id:1614010821, password:102258}数据
2、框架使用:
1)页面代码主要部分
sign-HTML
<div class="page-header">
<div class="page-header-image" style="background-image:url(assets/images/login.jpg)"></div>
<div class="container">
<div class="col-md-12 content-center">
<div id="app" class="card-plain">
<form method="post" th:action="@{/stu/toHomePage}">
<div class="header">
<div class="logo-container">
<img src="assets/images/logo.svg" alt="">
</div>
<h5>登录</h5>
</div>
<div class="content">
<div class="input-group input-lg">
<input id="id" type="text" class="form-control" placeholder="请输入学生号" v-model="id"/>
<span class="input-group-addon">
<i class="zmdi zmdi-account-circle"></i>
</span>
</div>
<div class="input-group input-lg">
<input id="password" type="password" placeholder="请输入密码" class="form-control" v-model="password"/>
<span class="input-group-addon">
<i class="zmdi zmdi-lock"></i>
</span>
</div>
<div style="color:#ff7878;" v-text="content"></div>
</div>
<div class="footer text-center">
<b-button id="submitStu" class="btn btn-primary btn-round btn-lg btn-block " @click="submitForm">SIGN IN</b-button>
<h5><a href="forgot-password.html" class="link">忘记密码?</a></h5>
</div>
</form>
</div>
</div>
</div>
</div>
2)Jquery.ajax
$(function(){
var student = {};
var username = $("#username").val();
var password = $("#password").val();
$("#submitStu").click(function () {
$.ajax({
method:"GET",
url:"stu/stuChecked?id=" + $("#username").val() + "&password=" + $("#password").val(),
success:function (stu){
student = stu;
// alert($.isEmptyObject(student))
if(!$.isEmptyObject(student)){
// alert("登录成功")
location.href="/mheal/stu/toQuesPage"
}else {
if(!$.isEmptyObject(username) && !$.isEmptyObject(password)){
$("#msg").text("用户名或密码不正确")
}else{
$("#msg").text("用户名或密码不能为空")
}
}
}
})
})
})
效果(依稀记得,回现有点费劲,遇到具体问题再具体解决):
- 前台可以收到json数据。由于先学的vue,后学的jquery,感觉舍弃vue,用jquery来实现代码可读性较差(看见那么多$,晕),而且操作dom对象让我很头疼,更喜欢vue的数据双向绑定
- 有点小问题,好像是对象判空,页面跳转出了问题
3)axios
var app = new Vue({
el: "#app",
data: {
id: "",
password: "",
content: "",
student: {},
},
methods: {
submitForm: async function () {
this.student = {}
// 用户名或密码为空
if (this.id.split(" ").join("").length === 0
|| this.password.split(" ").join("").length === 0) {
this.content = "用户名或密码不能为空"
return false
}
// 用户名或密码错误
else {
_this = this;
axios({
method: "GET",
url: "stu/stuChecked",
data: {
id: this.id,
password: this.password
}
}).then(function (res) {
_this.student = res.data;
// alert(_this.student)
}).catch(function (error) {
console.log(error);
});
try{
await axios.get("/mheal/stu/stuChecked?id="+this.id +"&password="+this.password).
then(res => {
//注意回调函数的this和vue的this会产生歧义
_this.student = res.data;
// console.log("res.data.data",res.data.data) undefined
// console.log("res.data",res.data) json
})
}catch (err){
console.log(err)
}
// alert("this.student" , this.student)
console.log(this.student)
if (!($.isEmptyObject(this.student))) {
alert("登陆成功")
this.content = ""
location.href = "/mheal/stu/toHomePage?id=" + this.id
}else {
this.content = "用户名或密码错误"
}
}
}
}
})
代码编写过程中出现的问题
1)axios异步查询时,后台可以打印数据,前台却得不到json数据,得到的结果为undefined
**疑问:**若通过axios回调函数,return值给vue的student对象,不知为什么得到的是undefined。但若不用return,直接用lambda表达式,直接在回调函数中将得到的json数据赋值给student,也还是undefined
**原因分析:**axios回调函数和vue的this关键字出现冲突
解决方法: 在axios外,_this = this,指明 _this是vue的关键字
2)axios异步查询时,前台虽然可以得到json数据,但是为什么对象判空时为true
**原因分析:**axios异步查询,该线程和主线程处理步骤不同,使得主线程得不到返回结果,就判空,数据不同步。
解决方法:在该方法中写上async,标明异步方法,并在取值时,用await去得到axios回调的结果
3、注意点说明
1)对象判空
-
什么是null,undefined? 参考文档
-
**对象判空的方法? ** jquery的$.isEmptyObject()
-
vue中获取对象,区别是全局,还是局部? 全局记得加this,局部用let定义,不用this
2)axios实现同步查询
- 用async,await
3)表单提交
-
用location.href实现表单提交,由于其为get方法,存在安全隐患,此问题待解决(毕设抓紧做要紧)
4)vue和bootstrap的整合,axios的导入
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="//unpkg.com/vue@latest/dist/vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>
注意用bootstrap-vue的b-button标签,vue才能操作bootstrap控件,否则没效果
4、最终效果
1)登录
2)注册(附上代码)
<div class="container">
<div class="col-md-12 content-center">
<div id="signUp" class="card-plain">
<form class="form" method="post" th:action="@{/stu/register}">
<div class="header">
<div class="logo-container">
<img th:src="@{/assets/images/logo.svg}" alt="">
</div>
<h5>注册</h5>
<!-- <span>Register a new membership</span> -->
</div>
<div class="content">
<div class="input-group">
<input type="text" class="form-control" placeholder="请输入学生号" name="id" v-model="id">
<span class="input-group-addon">
<i class="zmdi zmdi-account-circle"></i>
</span>
</div>
<div style="color: #ff7878" v-model="text1">{{text1}}</div>
<div class="input-group">
<input type="text" class="form-control" placeholder="请输入用户名" name="username" v-model="username">
<span class="input-group-addon">
<i class="zmdi zmdi-account-circle"></i>
</span>
</div>
<div style="color: #ff7878" v-model="text2">{{text2}}</div>
<div class="input-group">
<input type="text" class="form-control" placeholder="请输入邮箱" name="email" v-model="email">
<span class="input-group-addon">
<i class="zmdi zmdi-email"></i>
</span>
</div>
<div style="color: #ff7878" v-model="text3">{{text3}}</div>
<div class="input-group">
<input type="password" placeholder="请输入密码" class="form-control" name="password1" v-model="password1"/>
<span class="input-group-addon">
<i class="zmdi zmdi-lock"></i>
</span>
</div>
<div style="color: #ff7878" v-model="text4">{{text4}}</div>
<div class="input-group">
<input type="password" placeholder="重新确认密码" class="form-control" v-model="password2"/>
<span class="input-group-addon">
<i class="zmdi zmdi-lock"></i>
</span>
</div>
<div style="color: #ff7878" v-model="text5">{{text5}}</div>
</div>
<div class="footer text-center">
<!--注意使用b-button,否则vue不能操作bootstrap-->
<b-button class="btn btn-primary btn-round btn-lg btn-block waves-effect waves-light" @click="submitForm">SIGN UP</b-button>
</div>
</form>
</div>
</div>
</div>
var app = new Vue({
el: "#signUp",
data:{
flag: 0,
id: "",
username: "",
email: "",
password1: "",
password2: "",
text1: "",
text2: "",
text3: "",
text4: "",
text5: "",
student: {}
},
methods:{
submitForm: async function () {
this.flag = 0;
// 注意加this,表示vue与页面绑定的对象,以及如何判空
if($.isEmptyObject(this.id)){
this.text1 = "学生号不能为空"
}else {
this.flag++;
this.text1 = "";
}
if($.isEmptyObject(this.username)){
this.text2 = "用户名不能为空"
}else{
this.flag++;
this.text2 = ""
}
if($.isEmptyObject(this.email)){
this.text3 = "邮箱不能为空"
}else{
this.flag++;
this.text3 = ""
}
if($.isEmptyObject(this.password1)){
this.text4 = "密码不能为空"
}else{
this.flag++;
this.text4 = ""
}
if(!(this.password1 == this.password2)){
this.text5 = "密码输入不正确"
}else{
this.flag++
this.text5=""
}
if(this.flag == 5){
// alert(this.flag)
//注意axios的代码位置,避免代码顺序执行时,对象获取不到axios中返回的值
// alert(this.id)
// await axios({
// method:"GET",
// url:"/mheal/stu/stuChecked1?id=" + this.id,
// }).then(function (res) {
// this.student = res.data
// }).catch(function(error){
// console.log(error);
// })
_this = this
try{
await axios.get("/mheal/stu/stuChecked1?id=" + this.id)
.then(res => {
_this.student = res.data
})
}catch(err){
console.log(err);
alert("请求出错")
}
console.log(this.student)
if(!$.isEmptyObject(this.student)){
alert($.isEmptyObject(this.student))
this.text1 = "该学生号已注册"
}else{
alert("注册成功")
// location.href="/mheal/stu/register?"
// post提交表单
let formdata = new FormData()
formdata.append("id",this.id)
formdata.append("username",this.username)
formdata.append("password",this.password1)
formdata.append("email",this.email)
let config = {
headers: {
'Content-Type': 'multipart/form-data'
}
}
//异步提交表单,即使有返回页面,也不会实现页面跳转
axios.post('/mheal/stu/register',formdata,config).then(res => {
alert("提交表单")
})
location.href="/mheal/stu";
}
}
}
}
})
5、参考文档
2、vue async/await同步 案例 - 春风十里的情 - 博客园
3、javascript - axios错误处理的对象error.response 是空 - SegmentFault 思否
4、VUE判断可用对象是否为空 - BloggerYan - 博客园