二、前端登录改造
1、改造前端项目
现在我们的项目也能在我们本地跑起来了,从一开始就说我们的项目是前后端分离的项目,现在我们就把我们前端和后端的项目进行连接,通过我们后端一开始创建的用户进行登录,真正的实现前后端的联动效果。(我这里只是对登录进行简单的处理,因为我们项目也没有分权限什么的,所以现在以简单的实现为主,后期会有详细的一个大项目再具体说)
我们打开前端代码,现在我们刚才能登陆进去,用的是mock的数据,这里你可能会问,什么是mock,你记住以下这个就行,先作为了解。
前后端分离的开发模式,前端需要向后端请求数据(ajax请求),但实际开发过程中,前后端会约定一份接口文档,但前后端开发进度并不一致,当后端没有完善接口功能时,前端需要在本地模拟数据返回,此时需要使用到mockjs。
我们这个项目肯定是要连接我们的后台接口,所以这个mock我们就用不到了,所以我们将mock删掉或者禁掉即可。
删掉这个文件,然后再将引入mock文件的地方禁掉就OK了。
在文件src/main.js
中(注意为了方便以后我都这样写路径,意思是:在src文件下的main.js文件中)。Ctrl+/
把这一行禁掉,保存。然后在次启动项目,然后点击Sign in,会发现报错了,报错就对了,因为我们登录使用的是mock模拟的数据,现在我们不再使用mock了肯定就无法登录了。
这时,遇到事情不要慌,我们一点点的解决,下面我们要将我们的前后台的地址先进行连接上。
打开项目config/dev.env.js文件,我们可以看到项目调用的url前缀,在下面我们要把此处改为自己的服务接口地址。
其中dev.env.js和prod.env.js都改一下。(这里我要说一下小技巧,也是个开发的习惯,在我们修改别人的代码时,尽量使用注释掉,然后再写自己的,这样错了就能直接恢复了!)
当我们完成这一步,我们前后端的项目就实现了联动,当然现在还不能实现登录,我们还要做一些工作才能真正的前后端联动。
基本的工作做完了,接下来我们我们再运行下项目,看一下请求的地址有没有变化。打开浏览器,按一下F12,查看控制台,看到这个login的请求地址变成了我们刚才改的本地的地址了。接下来我们再了解一下前端登录的代码,虽然我们不需要编写,但是先了解了解。
2、登录接口请求详解
接下来先说一下原来是怎么登录的,可能这个比较枯燥,尤其对vue没有基础的同学,先了解就可。首先我们运行前端项目,相信大家现在都会如何运行项目了,打开浏览器控制台,现在我们点下登录,然后再刷新下页面,会看到有两个请求。
这时我们点开login,发现传入的是表单中的用户名和密码,但是应该还会有个返回的token值,可能是跨域的问题,我们先不管,或者使用mock的数据就能看到,我们先知道就好。
然后我们再点开info接口,传入的是前面的token,我们这里接口还没接好,所以暂时先了解就好,知道有这些东西。这个页面的东西就这些,接下来我们看前端代码,既然是登录,我们肯定要从登录的代码看起。我们先看路由的地方,打开src/api/login.js
,然后我们看到一个login方法,专门是登录的请求地址的,参数传递、请求的路径,这里说一下,如下图所示:
配置的这些再加上我们在config文件配置的地址,组合起来,看一下是不是我们经常在postman测试的地址,看到这里,你就会明白我们的数据请求地址是怎么来的了。
export function login(username, password) { return request({ url: '/user/login', method: 'post', data: { username, password } }) } export function getInfo(token) { return request({ url: '/user/info', method: 'get', params: { token } }) } export function logout() { return request({ url: '/user/logout', method: 'post' }) }
上边的代码,一共是三个方法,同样对应的是我们后端的三个接口,前两个是我们在登录页面上看到的,最后一个顾名思义是登出的接口。
接下来我们在看一下通过这个接口拿到数据又干了什么,打开src/views/login/index.vue,可以看到有一个handleLogin方法,专门用来处理登录校验的信息:
methods: { showPwd() { if (this.pwdType === 'password') { this.pwdType = '' } else { this.pwdType = 'password' } }, handleLogin() { this.$refs.loginForm.validate(valid => { if (valid) { this.loading = true this.$store.dispatch('Login', this.loginForm).then(() => { this.loading = false this.$router.push({ path: this.redirect || '/' }) }).catch(() => { this.loading = false }) } else { console.log('error submit!!') return false } }) }
可能有些同学会看不懂,没关系,我们先来看一下地址,dispatch到了Login,然后我们再去找这个Login方法,在/src/store/modules/user.js
文件中找到了这个Login方法。
// 登录 Login({ commit }, userInfo) { const username = userInfo.username.trim() return new Promise((resolve, reject) => { login(username, userInfo.password).then(response => { const data = response.data setToken(data.token) commit('SET_TOKEN', data.token) resolve() }).catch(error => { reject(error) }) }) }, // 获取用户信息 GetInfo({ commit, state }) { return new Promise((resolve, reject) => { getInfo(state.token).then(response => { const data = response.data if (data.roles && data.roles.length > 0) { // 验证返回的roles是否是一个非空数组 commit('SET_ROLES', data.roles) } else { reject('getInfo: roles must be a non-null array !') } commit('SET_NAME', data.name) commit('SET_AVATAR', data.avatar) resolve(response) }).catch(error => { reject(error) }) }) },
从上边的方法可以看到,这个就是实现那个api文件里的三个方法,在user.js最上边可以看到引入了那三个方法。
import { login, logout, getInfo } from '@/api/login'
这里我就说一下这个Promise
,译为承诺,是异步编程的一种解决方案,比传统的解决方案(回调函数)更加合理和更加强大。
1.这个对象它有三个状态:
● pending(进行中)
● fulfilled(已成功)
● rejected(已失败)
2.特点
● 对象的状态不受外界影响,只有异步操作的结果,可以决定当前是哪一种状态
● 一旦状态改变(从pending变为fulfilled和从pending变为rejected),就不会再变,任何时候都可以得到这个结果
3.流程
- 4.用法
Promise对象是一个构造函数,用来生成Promise实例
const promise = newPromise(function(resolve, reject) {});
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject
● resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”
● reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”
此时我们上边说过的dispatch这个方法的目的:
1.发送login请求获取到token值
2.并存储到Vuex状态管理模式中,供多个组件同时识别使用
3、数据响应
不知道大家还记不记得我们在写后端接口的时候,我们封装了一个返回类,如果不记得了可以打开后端代码看一下,我们在请求数据成功时,会返回请求的数据和一个code标识200
,代表我们接口请求成功了。这个vue-elemeent-template也有自己的请求拦截,我们这里需要改一下。
我们打开/src/utils/request.js
文件,在大约第9行的位置有个注释为请求超时时间,我们这里调的时间长一点,将5000ms
调成30000ms
(5秒调到30秒)
// 创建axios实例 const service = axios.create({ baseURL: process.env.BASE_API, // api 的 base_url timeout: 30000 // 请求超时时间 })
然后再往下找找,大概在27行左右,有个response拦截器注释,将20000改成我们自己定义的200
到这里我们前端的初始化工作基本上完成了,接下来我们要去后端处理登录了,从上边我们已经知道了,我们要登录就要两个接口,一个是login,另一个是info接口,接下来我们就根据这两个接口来写代码。
三、总结
本来感觉能写完的把登录,我一看篇幅写了很长了,就先把这个前端的作为结尾,后端的下一篇再写,估计这两天就可以了,希望大家不要放弃,坚持下去,为自己的梦想奋斗!