spa项目开发之登录注册(vue)

转载请标明出处:https://blog.csdn.net/men_ma/article/details/106847165.
本文出自 不怕报错 就怕不报错的小猿猿 的博客

spa项目开发之登录注册(vue)

  • 前言
  • 1.本次的目标
  • 2.spa项目完成登录注册布局
    • 2.1 第一步:
    • 2.2 第二步:
    • 2.3 第三步:
    • 2.4 第四步:
    • 2.5 第五步:
    • 2.6 看效果:
  • 3.Spa项目完成登录功能
  • 4.ajax 跨域问题
    • 4.1 什么叫跨域?
  • 5.axios 的 get/post 的区别( qs )
  • 6.This 指针带来的变量污染

前言

今日分享的是spa项目开发之登录注册,在这之前,我们要先搭建一个spa的项目,如何去搭建spa的项目呢?本篇知识与spa项目的搭建息息相关,建立在此基础之上,本博主在此附上搭建spa项目的博客链接,如下

链接: 如何使用Vue-cli搭建SPA项目?&如何在spa项目中使用路由?&嵌套路由的使用.

搭建好的spa项目结构图:
在这里插入图片描述
部分工具包的介绍:
在这里插入图片描述

另外本次目标需要两台服务器,前台(8088端口号)跟后台(8080端口号),所以需要Tomcat启动后台的服务器(eclipse),后台的项目搭建建立在maven项目基础之上

1.本次的目标

1、spa项目完成登录注册布局
2、Spa项目完成登录功能
3、 ajax 跨域问题
4、axios 的 get/post 的区别( qs )
5、T his 指针带来的变量污染

整个spa项目的结构图(贴出来):

先安装一下开发模块(命令):

npm install element-ui -S  //为了显示样式,跟导入js差不多
npm install axios -S	//需要ajax必须安装
npm install qs -S  //为了解决get和post的区别
npm install vue-axios -S	//是vue2提倡使用的轻量版的ajax

注意:一定要在项目的根路径下安装执行命令
在这里插入图片描述
在这里插入图片描述

查看上述安装是否成功安装到spa项目中去:
在这里插入图片描述

2.spa项目完成登录注册布局

2.1 第一步:

在这里需要用到element-ui,所以需要在main.js中导入,例如用到路由则导入路由

//导入命令
import 'element-ui/lib/theme-chalk/index.css'//使用elementUI
Vue.use(ElementUI)

在这里插入图片描述

2.2 第二步:

将如下css style样式的代码复制到App.vue中覆盖:

<style> 
html,
body {width: 100%;height: 100%;box-sizing: border-box;padding: 0px;margin: 0px;
}
#app {font-family: "Avenir", Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;color: #2c3e50;widows: 100%;height: 100%;
}
</style>

如下所示:
在这里插入图片描述

2.3 第三步:

数据库:
在这里插入图片描述

后台逻辑代码(关键类)UserAction.java:

public class UserAction extends BaseAction implements ModelDriven<User>{private UserBiz userBiz;private User user = new User();public UserBiz getUserBiz() {return userBiz;}public void setUserBiz(UserBiz userBiz) {this.userBiz = userBiz;}public String login() {ObjectMapper om = new ObjectMapper();JsonData jsonData = null;try {if(StringUtils.isBlank(user.getUname()) || StringUtils.isBlank(user.getPwd())) {jsonData = new JsonData(0, "用户或者密码为空", user);}else {User u = this.userBiz.login(user);
//				Map<String, Object> claims = new HashMap<String, Object>();
//				claims.put("uname",user.getUname());
//				claims.put("pwd", user.getPwd());
//				String jwt = JwtUtils.createJwt(claims, JwtUtils.JWT_WEB_TTL);
//				response.setHeader(JwtUtils.JWT_HEADER_KEY, jwt);jsonData = new JsonData(1, "登录成功", u);}} catch (Exception e) {e.printStackTrace();jsonData = new JsonData(0, "用户或者密码错误", user);}finally {try {ResponseUtil.write(response, om.writeValueAsString(jsonData));} catch (Exception e) {e.printStackTrace();}}return null;}public String getAsyncData() {ObjectMapper om = new ObjectMapper();try {Thread.sleep(6000);ResponseUtil.write(response, om.writeValueAsString("http://www.javaxl.com"));} catch (Exception e) {e.printStackTrace();}return null;}@Overridepublic User getModel() {return user;}
}

Login.vue:
**注意:**后台的属性名与前台的v-model绑定文本框的数据的属性名一定要一致,不然无效

<template><div class="login-wrap"><el-form :model="ruleForm" ref="ruleForm" label-width="100px" class="demo-ruleForm login-container"><h3 style="text-align: center;">用户登录</h3><el-form-item label="用户名" prop="unameuname"><el-input type="uname" v-model="ruleForm.uname" autocomplete="off"></el-input></el-form-item><el-form-item label="密码" prop="pwd"><el-input type="pwd" v-model="ruleForm.pwd" autocomplete="off"></el-input></el-form-item><el-form-item><el-row><el-col :span="24"><div class="grid-content bg-purple-dark"><el-button type="primary" style="width: 100%;" @click="doSub">提交</el-button></div></el-col></el-row><el-row><el-col :span="12"><div class="grid-content bg-purple"><el-link type="success" @click="toReg">用户注册</el-link></div></el-col><el-col :span="12"><div class="grid-content bg-purple-light"><el-link type="success">忘记密码</el-link></div></el-col></el-row></el-form-item></el-form></div>
</template><script>/* import qs from 'qs' */		//相当于把js文件导进来,当不用http.js工具类时需要导入export default {data() {return {ruleForm: {uname: 'zs',pwd: '123'}};},methods: {toReg() {this.$router.push({path: '/Reg'});},doSub() {//用工具类时的方法let url = this.axios.urls.SYSTEM_USER_DOLOGIN;//不用工具类时的方法//let url = 'http://localhost:8080/T216_SSH/vue/userAction_login.action';console.log(url);//post方式提交//这个this代表vue的实例this.axios.post(url, this.ruleForm).then((response) => {console.log(response);if (response.data.code == 1) {//这个this代表这个方法function(response)(用es6的箭头函数解决this指针带来的变量污染)this.$message({//登录成功消息提示message: response.data.msg,type: 'success'});} else {this.$message({//用户或密码错误消息提示message: response.data.msg,type: 'warning'});} //alert(111)//get方式提交/* this.axios.get(url, {params:this.ruleForm}).then((response) => {console.log(response);if (response.data.code == 1) {//这个this代表这个方法function(response)(用es6的箭头函数解决this指针带来的变量污染)this.$message({//登录成功消息提示message: response.data.msg,type: 'success'});} else {this.$message({//用户或密码错误消息提示message: response.data.msg,type: 'warning'});} */}).catch(function(error) {console.log(error);});}}}
</script><style scoped>.login-wrap {box-sizing: border-box;width: 100%;height: 100%;padding-top: 10%;background-image: url(data:image/svg+xml;base64, //这里有一个图片地址,特别长,为了博主给去掉了;/* background-color: #112346; */background-repeat: no-repeat;background-position: center right;background-size: 100%;}.login-container {border-radius: 10px;margin: 0px auto;width: 350px;padding: 30px 35px 15px 35px;background: #fff;border: 1px solid #eaeaea;text-align: left;box-shadow: 0 0 20px 2px rgba(0, 0, 0, 0.1);}.title {margin: 0px auto 40px auto;text-align: center;color: #505458;}
</style>

2.4 第四步:

加入Login.vue组件到index.js中:

//导入vue文件
import Login from '@/views/Login'
import Reg from '@/views/Reg'//配置路由线路{path: '/',name: 'Login',component: Login},{path: '/Login',name: 'Login',component: Login},{path: '/Reg',name: 'Reg',component: Reg}

在这里插入图片描述

2.5 第五步:

Reg.vue:复制一下Login,vue,修改一下调用的方法就好了
在这里插入图片描述
在这里插入图片描述

2.6 看效果:

第一步:
在这里插入图片描述

第二步:
在这里插入图片描述

第三步:

在这里插入图片描述

3.Spa项目完成登录功能

第一步:导入工具包(两个类)
action.js:

/*** 对后台请求的地址的封装,URL格式如下:* 模块名_实体名_操作*/
export default {'SERVER': 'http://localhost:8080/T216_SSH', //服务器'SYSTEM_USER_DOLOGIN': '/vue/userAction_login.action', //用户登陆'SYSTEM_USER_DOREG': '/vue/userAction_reg.action', //用户注册'SYSTEM_MENU_TREE': '/vue/treeNodeAction.action', //左侧树形菜单加载'SYSTEM_ARTICLE_LIST': '/vue/articleAction_list.action', //文章列表'SYSTEM_ARTICLE_ADD': '/vue/articleAction_add.action', //文章新增'SYSTEM_ARTICLE_EDIT': '/vue/articleAction_edit.action', //文章修改'SYSTEM_ARTICLE_DEL': '/vue/articleAction_del.action', //文章删除'SYSTEM_USER_GETASYNCDATA': '/vue/userAction_getAsyncData.action', //vuex中的异步加载数据'getFullPath': k => { //获得请求的完整地址,用于mockjs测试时使用return this.SERVER + this[k];}
}

http.js:

/*** vue项目对axios的全局配置*/
import axios from 'axios'
import qs from 'qs'//引入action模块,并添加至axios的类属性urls上
import action from '@/api/action'
axios.urls = action //action相当于action.js// axios默认配置
axios.defaults.timeout = 10000; // 超时时间
// axios.defaults.baseURL = 'http://localhost:8080/j2ee15'; // 默认地址
axios.defaults.baseURL = action.SERVER;//整理数据
// 只适用于 POST,PUT,PATCH,transformRequest` 允许在向服务器发送前,修改请求数据
axios.defaults.transformRequest = function(data) {data = qs.stringify(data);return data;
};// 请求拦截器
axios.interceptors.request.use(function(config) {// var jwt = window.vm.$store.getters.getJwt;// config.headers['jwt'] = jwt;return config;
}, function(error) {return Promise.reject(error);
});// 响应拦截器
axios.interceptors.response.use(function(response) {// debugger;// var jwt = response.headers['jwt'];// if(jwt){// 	window.vm.$store.commit('setJwt',{jwt:jwt});// }return response;
}, function(error) {return Promise.reject(error);
});// // 路由请求拦截
// // http request 拦截器
// axios.interceptors.request.use(
// 	config => {
// 		//config.data = JSON.stringify(config.data);  
// 		//config.headers['Content-Type'] = 'application/json;charset=UTF-8';
// 		//config.headers['Token'] = 'abcxyz';
// 		//判断是否存在ticket,如果存在的话,则每个http header都加上ticket
// 		// if (cookie.get("token")) {
// 		// 	//用户每次操作,都将cookie设置成2小时
// 		// 	cookie.set("token", cookie.get("token"), 1 / 12)
// 		// 	cookie.set("name", cookie.get("name"), 1 / 12)
// 		// 	config.headers.token = cookie.get("token");
// 		// 	config.headers.name = cookie.get("name");
// 		// }
// 		return config;
// 	},
// 	error => {
// 		return Promise.reject(error.response);
// 	});// // 路由响应拦截
// // http response 拦截器
// axios.interceptors.response.use(
// 	response => {
// 		if (response.data.resultCode == "404") {
// 			console.log("response.data.resultCode是404")
// 			// 返回 错误代码-1 清除ticket信息并跳转到登录页面
// 			//      cookie.del("ticket")
// 			//      window.location.href='http://login.com'
// 			return
// 		} else {
// 			return response;
// 		}
// 	},
// 	error => {
// 		return Promise.reject(error.response) // 返回接口返回的错误信息
// 	});export default axios;

第二步:导入api(main.js)

//导入import axios from '@/api/http'  //用了工具类时
import VueAxios from 'vue-axios' //使用
Vue.use(VueAxios,axios)

在这里插入图片描述

第三步:利用axios的get/post的提交(前面Login.vue已附上)
在这里插入图片描述
第四步:运行结果(控制台)一定要记得启动后台Tomcat的服务器
在这里插入图片描述
在这里插入图片描述

4.ajax 跨域问题

4.1 什么叫跨域?

url地址:协议+ip+port+项目(四部分组成)
例如:
http://localhost:8080/T216_SSH/vue/treeNodeAction.action

只要四个部分中有一个部分不一样就属于跨域
例如:http://localhost:8080/T216_SSHhttp://localhost:8080/T216_SSH2http://localhost:8088/T216_SSHhttp://192.168.122.11:8080/T216_SSHhttps://localhost:8088/T216_SSH此上地址是属于跨域

附录一:ES6的语法箭头函数

doSomething(function(a){…});

doSomething((a)=>{});

过滤器CorsFilter.java

/*** 配置tomcat允许跨域访问* * @author Administrator**/
public class CorsFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}// @Override// public void doFilter(ServletRequest servletRequest, ServletResponse// servletResponse, FilterChain filterChain)// throws IOException, ServletException {// HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;//// // Access-Control-Allow-Origin就是我们需要设置的域名// // Access-Control-Allow-Headers跨域允许包含的头。// // Access-Control-Allow-Methods是允许的请求方式// httpResponse.addHeader("Access-Control-Allow-Origin", "*");// *,任何域名// httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT,// DELETE");// // httpResponse.setHeader("Access-Control-Allow-Headers", "Origin,// // X-Requested-With, Content-Type, Accept");//// // 允许请求头Token// httpResponse.setHeader("Access-Control-Allow-Headers",// "Origin,X-Requested-With, Content-Type, Accept, Token");// HttpServletRequest req = (HttpServletRequest) servletRequest;// System.out.println("Token=" + req.getHeader("Token"));// if("OPTIONS".equals(req.getMethod())) {// return;// }////// filterChain.doFilter(servletRequest, servletResponse);// }@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException {HttpServletResponse resp = (HttpServletResponse) servletResponse;HttpServletRequest req = (HttpServletRequest) servletRequest;// Access-Control-Allow-Origin就是我们需要设置的域名// Access-Control-Allow-Headers跨域允许包含的头。// Access-Control-Allow-Methods是允许的请求方式resp.setHeader("Access-Control-Allow-Origin", "*");// *,任何域名resp.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE");// resp.setHeader("Access-Control-Allow-Headers", "Origin,X-Requested-With,// Content-Type, Accept");// 允许客户端,发一个新的请求头jwtresp.setHeader("Access-Control-Allow-Headers", "Origin,X-Requested-With, Content-Type, Accept, jwt");// 允许客户端,处理一个新的响应头jwtresp.setHeader("Access-Control-Expose-Headers", "jwt");// String sss = resp.getHeader("Access-Control-Expose-Headers");// System.out.println("sss=" + sss);// 允许请求头Token// httpResponse.setHeader("Access-Control-Allow-Headers","Origin,X-Requested-With,// Content-Type, Accept, Token");// System.out.println("Token=" + req.getHeader("Token"));if ("OPTIONS".equals(req.getMethod())) {// axios的ajax会发两次请求,第一次提交方式为:option,直接返回即可return;}filterChain.doFilter(servletRequest, servletResponse);}@Overridepublic void destroy() {}
}

web.xml中配置:
在这里插入图片描述

注1:axios跨域问题会一直报错:“http://127.0.0.1:8848' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header”因为使用了前后端分离开发,跨域访问了,解决方案:需要配置tomcat允许跨域访问,tomcat跨域配置方法很多,但最简单的方式是自己写一个过滤器CorsFilter实现,添加一个响应头Access-Control-Allow-Origin即可httpResponse.addHeader("Access-Control-Allow-Origin", "*");//*表示任何域名httpResponse.addHeader("Access-Control-Allow-Origin", "http://localhost:80");Access-Control-Allow-Origin:*                           #则允许所有域名的脚本访问该资源。Access-Control-Allow-Origin:https://www.fujieace.com    #允许特定的域名访问注2:axios.get提交没有问题,axios.post提交后台接收不到数据因为POST提交的参数的格式是Request Payload,这样后台取不到数据的解决方案:使用qs.js库,将{a:'b',c:'d'}转换成'a=b&c=d'注3:为简化axios使用,还可以使用axios全局配置及拦截器,详情见资料“api/http.js”axios.defaults.baseURL = 'https://api.example.com';//axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;//自定义请求头,添加认证令牌axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';注4:为方便开发,建议对请求地址进行封装,详情见资料“api/action.js”注5:^_^~~~~为进一步简化开发,将action.js的URL地址封装到axios.urls属性上         

5.axios 的 get/post 的区别( qs )

 1.题外话:vue.js有著名的全家桶系列:vue-router,vuex, vue-resource,再加上构建工具vue-cli,就是一个完整的vue项目的核心构成。其中vue-resource是Vue.js的一款插件,它可以通过XMLHttpRequest或JSONP发起请求并处理响应,但在vue更新到2.0之后,作者就宣告不再对vue-resource更新,而是推荐的axios2.GET提交axios.get('/user', {//注意数据是保存到json对象的params属性params: {ID: 12345}}).then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});3.POST提交axios.post('/user', {//注意数据是直接保存到json对象firstName: 'Fred',lastName: 'Flintstone'}).then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});

在这里插入图片描述
在这里插入图片描述

6.This 指针带来的变量污染

在这里插入图片描述
在这里插入图片描述

我太难了


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部