Vue中使用axios(Ajax)+ElementUI实现登录

一、引入和配置使用ElementUI框架

1.使用vue-cli脚手架工具创建一个vue项目

vue init webpack 项目名

Vue中使用axios(Ajax)+ElementUI实现登录_第1张图片

2.npm安装elementUI

cd 项目名                                            #进入新建项目的根目录
npm install element-ui -S                           #安装element-ui模块

 Vue中使用axios(Ajax)+ElementUI实现登录_第2张图片

 

3.配置ElementUI

main.js全局配置

        配置element-ui,使用elementUI来进行布局

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
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
 
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: ''
})

二、Vue+ElementUI设计登陆页面

前往ElementUI复制组件

登录组件:Login.vue


 

 
  • 使用到Element的表单 
  • 使用到Element的栅格布局
  • 使用到Element的Link 文字链接

 配置路由:index.js

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
 
//登录
import Login from '@/views/Login'
//注册
import Register from '@/views/Register'
 
Vue.use(Router)
 
export default new Router({
  routes: [
    {
      path: '/HelloWorld',
      name: 'HelloWorld',
      component: HelloWorld
    },{
      path: '/',
      name: 'Login',
      component: Login
    },{
      path: '/Register',
      name: 'Register',
      component: Register
    }
  ]
})

修改端口号

config中的index.js

Vue中使用axios(Ajax)+ElementUI实现登录_第3张图片

注释图片不显示

App.vue

Vue中使用axios(Ajax)+ElementUI实现登录_第4张图片

登录布局展示

Vue中使用axios(Ajax)+ElementUI实现登录_第5张图片

三、前后端交互

1.axios简介

        axios是vue2提倡使用的轻量版的ajax。它是基于promise的HTTP库。它会从浏览器中创建XMLHttpRequests,与Vue配合使用非常好。

2.GET提交

前端Login.vue:

后端:

public class UserAction extends DispatcherAction implements ModelDriver {
	private User user=new User();
	private ObjectMapper mapper=new ObjectMapper();
	private UserDao userDao=new UserDao();
	@Override
	public User getModel() {
		return user;
	}

	public String userLogin(HttpServletRequest req,HttpServletResponse resp) 
			throws ServletException,IOException{
		Map json=new HashMap();
		User us = userDao.userLogin(user);
		if(null!=us) {
			json.put("code","1");
			json.put("msg", "登录成功");
		}else {
			json.put("code", "-1");
			json.put("msg", "用户名或密码错误");
		}
		
		mapper.writeValue(resp.getOutputStream(),json);
		return null;
	}
}

Dao方法:

public class UserDao extends BaseDao{
	/**
	 * 根据用户名密码查询对应的用户对象信息
	 * @param user
	 * @return
	 */
	public User userLogin(User user) {
		String sql="select * from t_user_vue where"
				+ " username='"+user.getUsername()+"' and password='"+user.getPassword()+"'";
		System.out.println(sql);
		@SuppressWarnings("unchecked")
		List lst=super.executeQuery(sql, null, new CallBack() {
			@Override
			public List forEach(ResultSet rs) throws SQLException {
				return CommonUtils.toList(rs, User.class);
			}
		});
		if(null!=lst&&lst.size()!=0)
			return lst.get(0);
		else
			return null;
	}
}

 演示:

Vue中使用axios(Ajax)+ElementUI实现登录_第6张图片

3.POST提交

  import axios from 'axios'
  import qs from 'qs' 
  export default{
    name:'Register',
    data:function(){
      return {
        username:'admin',
        password:'123'
      }
    },
    methods:{
      doLogin:function(){
        let username=this.username;
        let password=this.password;
        //定义请求路径
        let url='http://localhost:8080/j2eeVue/userAction.action';
        //定义请求参数
        let params={
            username:username,
            password:password,
            methodName:'userLogin'
        };
        console.log(params);
        //发起ajax请求POST
        //payload:{a:'zs',b:'ls'} -> a=zs&b=ls
        //把请求参数转换格式
        let str=qs.stringify(params); 
        axios.post(url,str).then(resp=>{

          let data=resp.data;
          this.$message({
              message: data.msg,
              type: data.code==1?'success':'error'
          });
        }).catch(err=>{
          console.log(err);
        }); 
      },
      toRegister:function(){
        this.$router.push('/Register');
      }
    }
  }

3.axios封装

如果每个组件都要用axios那就要一直导入axios,我们不如把它给封装起来

先写封装与全局访问

action.js:

/**
 * 对后台请求的地址的封装,URL格式如下:
 * 模块名_实体名_操作
 */
export default {
    'SERVER': 'http://localhost:8080/j2eeVue', //服务器
    'SYSTEM_USER_DOLOGIN': '/userAction.action', //登陆
    '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
 
// 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);
});
 
// // 路由请求拦截
// // 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;


配置全局main.js文件

import axios from '@/api/http'             //vue项目对axios的全局配置
import VueAxios from 'vue-axios'
Vue.use(VueAxios,axios)

再实现登录方法就不需要再去引入axios和qs

 使用后的登录方法:






四、Ajax跨域问题

什么是跨域问题?

跨域问题来源于JavaScript的"同源策略",即只有 协议+主机名+端口号 (如存在)相同,则允许相互访问。也就是说JavaScript只能访问和操作自己域下的资源,不能访问和操作其他域下的资源。跨域问题是针对JS和ajax的,html本身没有跨域问题。

查看浏览器开发者工具Console报错:

Vue中使用axios(Ajax)+ElementUI实现登录_第7张图片

Failed to load http://a.a.com:8080/A/FromServlet?userName=123: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://b.b.com:8080' is therefore not allowed access.

  • http://www.abc.com/a/b 调用 http://www.abc.com/d/c(非跨域)
  • http://www.abc.com/a/b 调用 http://www.def.com/a/b (跨域:域名不一致)
  • http://www.abc.com:8080/a/b 调用 http://www.abc.com:8081/d/c (跨域:端口不一致)
  • http://www.abc.com/a/b 调用 https://www.abc.com/d/c (跨域:协议不同)

请注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。


跨域问题解决 

web.xml


  
      corsFilter
      com.zking.vue.util.CorsFilter
  
  
      corsFilter
      /*
   

CorsFilter.java

package com.zking.vue.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 CorsFilter 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", "Origin, X-Requested-With, Content-Type, Accept");
        httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE");
        filterChain.doFilter(servletRequest, servletResponse);
    }
    @Override
    public void destroy() {
 
    }
}

 五、POST传参问题

当使用get提交的时候没有问题,但是使用post提交后台接收不到数据,为什么呢?

因为POST提交的参数的格式是Request Payload,这样后台取不到数据的

解决方案:

        使用qs.js库,将{a:'b',c:'d'}转换成'a=b&c=d'

六、箭头函数 

ES6标准新增了一种新的函数:Arrow Function(箭头函数)。

1.基本语法

ES6中允许使用箭头=>来定义箭头函数,具体语法,我们来看一个简单的例子:

// 箭头函数
let fun = (name) => { // 函数体 return `Hello ${name} !`; }; // 等同于 let fun = function (name) { // 函数体 return `Hello ${name} !`; };

可以看出,定义箭头函在数语法上要比普通函数简洁得多。箭头函数省去了function关键字,采用箭头=>来定义函数。函数的参数放在=>前面的括号中,函数体跟在=>后的花括号中。

关于箭头函数的参数:

  1. 如果箭头函数没有参数,直接写一个空括号即可。
  2. 如果箭头函数的参数只有一个,也可以省去包裹参数的括号。
  3. 如果箭头函数有多个参数,将参数依次用逗号(,)分隔,包裹在括号中即可。

// 没有参数
let fun1 = () => { console.log(111); }; 

// 只有一个参数,可以省去参数括号 
let fun2 = name => { console.log(`Hello ${name} !`) }; 

// 有多个参数 
let fun3 = (val1, val2, val3) => { return [val1, val2, val3]; };

关于箭头函数的函数体:

①如果箭头函数的函数体只有一句代码,就是简单返回某个变量或者返回一个简单的JS表达式,可以省去函数体的大括号{ }。

let f = val => val; 
// 等同于 
let f = function (val) { return val }; 
let sum = (num1, num2) => num1 + num2; 
// 等同于 
let sum = function(num1, num2) { return num1 + num2; }; 

②如果箭头函数的函数体只有一句代码,就是返回一个对象,可以像下面这样写:

// 用小括号包裹要返回的对象,不报错

let getTempItem = id => ({ id: id, name: "Temp" }); 
// 但绝不能这样写,会报错。 
// 因为对象的大括号会被解释为函数体的大括号 
let getTempItem = id => { id: id, name: "Temp" };

③如果箭头函数的函数体只有一条语句并且不需要返回值(最常见是调用一个函数),可以给这条语句前面加一个void关键字

let fn = () => void doesNotReturn(); 

箭头函数最常见的用处就是简化回调函数。

// 例子一
// 正常函数写法
[1,2,3].map(function (x) { return x * x; }); 
// 箭头函数写法 
[1,2,3].map(x => x * x); 

// 例子二 
// 正常函数写法 
var result = [2, 5, 1, 4, 3].sort(function (a, b) { return a - b; }); 
// 箭头函数写法 
var result = [2, 5, 1, 4, 3].sort((a, b) => a - b);

2.特点

  • 1. 箭头函数使表达更加简洁,隐式返回值
  • 2. 没有自己的this
  • 3. 箭头函数不能当作构造函数使用、不能使用new
  • 4. 不能使用argumetns,取而代之用rest参数...解决
  • 5. 箭头函数没有原型对象

你可能感兴趣的:(Vue,vue.js,elementui,javascript,ajax,axios)