ElementUI之登录+注册
一.elementUI的使用
1.使用vue-cli构建SPA项目
**第一步:**使用CMD命令窗口,并跳转到指定项目目录下
E:\> cd vueProject
**第二步:**使用命令vue init webpack 项目名,构建一个vue项目
vue init webpack hispro
**第三步:**使用命令npm install element-ui -S,添加Element-UI模块
npm install element-ui -S
最后,打开项目的package.json文件可查看具体添加模块信息。
2.登录+注册静态页实现
**第一步:**在src目录下创建views目录(该目录用于存放vue组件)。
**第二步:**在main.js中引入element-ui模块
在项目中src目录下找到main.js
,并在指定位置添加三行代码:
import Vue from 'vue'
// 新添加1
import ElementUI from 'element-ui'
// 新添加2,避免后期打包样式不同,要放在import App from './App';之前
import 'element-ui/lib/theme-chalk/index.css'
import App from './App'
import router from './router'
// 新添加3
Vue.use(ElementUI)
Vue.config.productionTip = false
3.创建用户登录组件
**第三步:**创建用户登录组件
<template> <div class="login-wrap"> <el-form class="login-container"> <h1 class="title">用户登录</h1> <el-form-item label=""> <el-input type="text" v-model="username" placeholder="登录账号" autocomplete="off"></el-input> </el-form-item> <el-form-item label=""> <el-input type="password" v-model="password" placeholder="登录密码" autocomplete="off"></el-input> </el-form-item> <el-form-item> <el-button type="primary" style="width:100%;" @click="doSubmit()">提交</el-button> </el-form-item> <el-row style="text-align: center;margin-top:-10px"> <el-link type="primary">忘记密码</el-link> <el-link type="primary" @click="gotoRegister()">用户注册</el-link> </el-row> </el-form> </div> </template>
4.配置路由
在router/index.js
中修改vue项目默认显示路由:
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
// 导入Login登录组件
import Login from '@/views/Login'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/', //设置默认显示路由
name: 'Login',
component: Login
},
{
path: '/HelloWorld',
name: 'HelloWorld',
component: HelloWorld
}
]
})
5.修改项目端口并启动
不能与后端一同使用8080端口
在config/index.js
目录下修改vue项目运行端口:
const path = require('path')
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {},
// Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST
port: 8083, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: true,
...
},
build: {
...
}
}
在cmd界面使用npm run dev运行项目
运行结果如图
elementUI已经成功导入
二.axios前后端交互
1.安装axios
axios是vue2提倡使用的轻量版的ajax。它是基于promise的HTTP库。它会从浏览器中创建XMLHttpRequests,与Vue配合使用非常好。
题外话:vue.js有著名的全家桶系列:vue-router,vuex, vue-resource,再加上构建工具vue-cli,就是一个完整的vue项目的核心构成。 其中vue-resource是Vue.js的一款插件,它可以通过XMLHttpRequest或JSONP发起请求并处理响应,但在vue更新到2.0之后,作者就宣告不再对vue-resource更新,而是推荐的axios
npm i axios -S
在login.vue的
import axios from 'axios'
2.axios之get
使用axios的get请求方式,必须将请求参数保存到json对象的params属性中。
<script>
import axios from 'axios'
export default {
name: 'Login',
data: function() {
return {
username: "admin",
password: "123"
}
},
methods: {
doSubmit: function() {
let params = {
username: this.username,
password: this.password
};
console.log(params);
var url = "http://localhost:8080/ssm/user/userLogin";
axios.get(url, { //注意数据是保存到json对象的params属性
params: params
}).then(function(response) {
console.log(response);
}).catch(function(error) {
console.log(error);
});
}
}
}
</script>
在前台发送请求,查看控制台
三.axios的get请求与post请求的区别及优化
使用axios的post请求方式,直接将请求参数保存到json对象中即可。
<script>
import axios from 'axios'
import qs from 'qs'
export default {
name: 'Login',
data: function() {
return {
username: "admin",
password: "123"
}
},
methods: {
doSubmit: function() {
let params = {
username: this.username,
password: this.password
};
console.log(params);
var url = "http://localhost:8080/ssm/user/userLogin";
//通过qs中的stringify方法进行格式转换
let str=qs.stringify(params);
//注意数据是保存到json对象的params属性
axios.post(url, str).then(function(response) {
console.log(response);
}).catch(function(error) {
console.log(error);
});
}
}
}
</script>
问题点:post请求数据格式问题
axios.get提交没有问题,axios.post提交后台接收不到数据,因为POST提交的参数的格式是Request Payload,这样后台取不到数据的。
解决方法:使用qs.js库,将{a:‘b’,c:‘d’}转换成’a=b&c=d’
## 下载qs库
npm install qs -S
## 在Login.vue组件中导入qs
import qs from 'qs'
## 通过qs的stringify方法进行格式转换
let str=qs.stringify(params);
后台成功接受数据并返回:
Axios是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范。
vue-axios是在axios基础上扩展的插件,在Vue.prototype原型上扩展了$http等属性,可以更加方便的使用axios。
通过vue-axios实现对axios的轻量封装:
**第一步:**下载安装vue-axios
npm i vue-axios -S
**第二步:**导入api模块,添加axios的全局配置
将api模块导入到SPA项目的src目录下,其中api模块包含了action.js(针对后台请求接口的封装定义)和http.js(针对axios的全局配置)两个文件。
- action.js
export default {
'SERVER': 'http://localhost:8080/ssm', //服务器
'SYSTEM_USER_DOLOGIN': '/user/userLogin', //登陆
'SYSTEM_USER_DOREG': '/userAction.action', //注册
'getFullPath': k => { //获得请求的完整地址,用于mockjs测试时使用
return this.SERVER + this[k];
}
}
对后台请求的地址的封装,URL格式:模块名_实体名_操作
- http.js
import axios from 'axios'
import qs from 'qs'
//引入action模块,并添加至axios的类属性urls上
import action from '@/api/action'
axios.urls = action
// 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) {
return config;
}, function(error) {
return Promise.reject(error);
});
// 响应拦截器
axios.interceptors.response.use(function(response) {
return response;
}, function(error) {
return Promise.reject(error);
});
export default axios;
**第三步:**修改main.js配置vue-axios
在main.js文件中引入api模块和vue-axios模块
import axios from '@/api/http'
import VueAxios from 'vue-axios'
Vue.use(VueAxios,axios)
第四步:修改.Vue文件代码.不必再引入axios和qs,直接使用this来调用http.js内的axios,同时参数直接传入paramr即可,http.js中的拦截器会拦截该参数自动使用qs来修饰数据
<script>
export default {
name: 'Login',
data: function() {
return {
username: "admin",
password: "123"
}
},
methods: {
doSubmit: function() {
let params = {
username: this.username,
password: this.password
};
console.log(params);
var url =this.axios.urls.SYSTEM_USER_DOLOGIN;;
//注意数据是保存到json对象的params属性
this.axios.post(url,params).then(function(response) {
console.log(response);
}).catch(function(error) {
console.log(error);
});
}
}
}
</script>
四.跨域现象及解决方案
http://localhost:8080/ssm
协议,ip(host),port,项目有一个不一致时.就会发生跨域
跨域现象
解决方法:
在web.xml配置跨域过滤器
<!--CrosFilter跨域过滤器-->
<filter>
<filter-name>corsFilter</filter-name>
<filter-class>com.zking.ssm.util.CorsFilter2</filter-class>
</filter>
<filter-mapping>
<filter-name>corsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
corsFilter.java
package com.zking.ssm.util;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
/**
* 配置tomcat允许跨域访问
*
* @author Administrator
*
*/
public class CorsFilter2 implements Filter {
@Override
public 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.setHeader("Access-Control-Allow-Origin", "*");// *,任何域名
httpResponse.setHeader("Access-Control-Allow-Headers", "responseType,Origin, X-Requested-With, Content-Type, Accept");
httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE");
//允许客户端处理一个新的响应头jwt
//httpResponse.setHeader("Access-Control-Expose-Headers", "jwt,Content-Disposition");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
Origin", “*”);// *,任何域名
httpResponse.setHeader(“Access-Control-Allow-Headers”, “responseType,Origin, X-Requested-With, Content-Type, Accept”);
httpResponse.setHeader(“Access-Control-Allow-Methods”, “POST, GET, PUT, DELETE”);
//允许客户端处理一个新的响应头jwt
//httpResponse.setHeader("Access-Control-Expose-Headers", "jwt,Content-Disposition");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}