1、登录页面-样式调整
登录页整体思路如下:
-
表单验证(login/index.vue)
-
utils/validate.js ---> validMobile
-
收集用户的参数,调用actions
-
调用 api/user.js中封装好的api
-
找到axios实例:utils/request.js中获取axios实例 -
设置基地址从环境变量中
-
经过请求拦截器,添加请求头(添加token, utils/request.js) -
代理转发(vue.config.js) -
后端服务器要启动,mongoDB也要启动;后端才能收到请求,返回数据 -
经过响应拦截器的处理(utils/request.js)
-
判断当前操作是否成功,决定是否axios报错 -
简化获取有效数据的写法(脱壳)
-
得到api调用之后结果(login.vue) -
保存token到vuex,调用mutations(store/modules/user.js) -
token做持久化(utils/auth.js)
1.1设置登录表单的logo图
在views/login/index.vue
<!-- 放置标题图片 @是设置的别名-->
<div class="title-container">
? ?<h3 class="title">
? ? ?<img src="@/assets/common/login-logo.png" alt="">
? ?</h3>
</div>
@ 是我们在vue.config.js中设置的一个路径别名,指向src根目录,这样可以很方便的寻找文件
1.2设置背景图片
views/login/index.vue
<style lang="scss">
.login-container {
?background-image: url('~@/assets/common/login.jpg'); // 设置背景图片
?background-position: center; // 将图片位置设置为充满整个屏幕
}
解释一下为什么加 ~ :
当在样式表中使用@别名的时候,必须要在@前面加上~这个符号,否则不识别。(固定用法)
1.3设置输入框中的字体颜色
$light_gray: #68b0fe; // 将输入框颜色改成蓝色
1.4设置登录按钮的样式
在el-button 上补充一个loginBtn的class,并设置样式如下
.loginBtn {
?background: #407ffe;
?height: 64px;
?line-height: 32px;
?font-size: 24px;
}
1.5修改显示在Login页面上的提示文本
<div class="tips">
? <span style="margin-right:20px;">账号: 13800000002</span>
? <span> 密码: 123456</span>
</div>
1.6设置输入表单整体背景色: 输入框的背景色
/* reset element-ui css */
.el-form-item {
? ?border: 1px solid rgba(255, 255, 255, 0.1);
? ?background: rgba(255, 255, 255, 0.7); // 输入登录表单的背景色
? ?border-radius: 5px;
? ?color: #454545;
}
1.7设置错误信息的颜色**
当表单元素的输入验证错误时,它会在相应的表单元素下边出现一个文字说明。
/* reset element-ui css */
.el-form-item__error {
color: #fff
}
2、登录页面-改造登录表单中的数据项
1.1按照接口文档的要求,修改已有代码中的表单数据绑定
使用vscode中的替换功能
在login/index.vue中 按shift+f 区分大小写,将username全部换成mobile
查看接口文档,在当前页面中做替换。
loginForm: {
? ? ? ?mobile: '13800000002',
? ? ? ?password: '123456'
? ? },
2.2自定义校验规则
utils/validate.js中
export function validMobile(str) {
?return /^1[3-9]\d{9}$/.test(str) // 校验手机号
}
在login/index.vue中引入
// 引入手机号校验规则
import { validMobile } from '@/utils/validate'
?data() {
? // 自定义校验规则
? ?const validateMobile = (rule, value, callback) => {
? ? ?console.log(value)
? ? ? // 如果validMobile的value符合校验规则 则手机号验证通过
? ? ?if (validMobile(value)) {
? ? ? ?callback()
? ? } else { // 否则提示手机号格式错误
? ? ? ?callback(new Error('手机号格式错误'))
? ? }
? }
? ?return {
? ? ?loginForm: {
? ? ? ?mobile: '13800000002',
? ? ? ?password: '123456'
? ? },
?
? ? ?loginRules: {
? ? ? // 手机号的校验规则
? ? ? ?mobile: [{ required: true, trigger: 'blur', validator: validateMobile }],
? ? ? // 密码的校验规则
? ? ? ?password: [
? ? ? ? { required: true, trigger: 'blur', message: '密码不能为空' },
? ? ? ? { min: 6, max: 16, message: '密码的长度在6-16位之间 ', trigger: 'blur' }
? ? ? ]
? ? },
? ? ?loading: false,
? ? ?passwordType: 'password',
? ? ?redirect: undefined
? }
},
3、修改axios的响应拦截器
bug:登录时,填写错误的用户名密码,没有报错提示(没有进入catch分支)
解决方法
在request.js中添加 响应拦截器
// 响应拦截器
service.interceptors.response.use(response => {
?console.log('所有的响应结果在这:', response)
// 如果success 是true 就是操作成功
?if (response.data.success) {
? // 操作成功
} else {
? // 如果success是false 业务出错 直接触发reject
? // 被catch分支捕获
? ?return Promise.reject(new Error('请求失败'))
}
}, error => {
?return Promise.reject(error) // 返回执行错误 让当前的执行跳转出成功 直接进入catch
})
4、解决观察返回值需要 res.data.data的问题
只需要一行代码就可以解决
5、token-处理
整体思路
5.1将token保存到vuex中
store/user.js中
export default {
?namespaced: true,
?state: {
? ?token: ''
},
?mutations: {
? ?setToken(state, newToken) {
? ? ?state.token = newToken
? }
},
?actions: {
}
}
在login/indexvue中 如何调用mutation
? // 做登录的动作
? ?async doLogin() {
? ? ?try {
? ? ? ?const res = await login(this.loginForm)
? ? ? ?console.log('登录的接口结果是:', res)
?
? ? ? // 保存token到vuex
? ? ? // 在组件中调用mutation
? ? ? ?this.$store.commit('user/setToken', res.data)
? ? } catch (err) {
? ? ? ?alert('登录失败')
? ? }
? },
配置axios请求拦截器
将登陆获取到的token统一注入到接口的请求头中 。
请求拦截器代码
在文件src/utils/request.js 中:
-
引入store - import store from '@/store'
// 请求拦截 :添加请求头 携带token信息
service.interceptors.request.use((config) => {
?const token = store.state.user.token
?if (token) {
? ?config.headers['Authorization'] = `Bearer ${token}`
}
?
?return config
}, error => {
?return Promise.reject(error) // 返回执行错误
})
// Authorization和bearer 是本项目的后端接口要求的写法。
?
?
6、token-处理-持久化
现在的token是保存在vuex中,而页面刷新之后,vuex的内容丢失了,将会导致接口访问异常。所以我们需要对token做持久化处理: 刷新页面之后token不丢失。
在utils/auth.js
import Cookies from 'js-cookie'
?
const TokenKey = 'vue_admin_template_token'
?
export function getToken() {
?return Cookies.get(TokenKey)
}
?
export function setToken(token) {
?return Cookies.set(TokenKey, token)
}
?
export function removeToken() {
?return Cookies.remove(TokenKey)
}
在vuex中引入方法,并调用
在store/modules/user.js 文件中,
import { getToken, setToken, removeToken } from '@/utils/auth'
?
?
export default {
?namespaced: true,
?state: {
? ?token: getToken() || null // 默认为null
},
// 修改状态
?mutations: {
? // 设置token
? ?setToken(state, newToken) {
? ? ?state.token = newToken
? ? // 本地存一下
? ? ?setToken(newToken)
? },
?
? // 删除vuex的token---用于登出时
? ?removeToken(state) {
? ? ?state.token = null
? ? // 删除本地token
? ? // 本地存一下
? ? ?removeToken()
? }
},
7、在vuex中的action里发登陆请求
在store/modules/user.js 中,写actions如下:
export default {
// ... 省略其他
actions: {
? // data表示接口参数
? ?async userLogin(context, obj) {
? ? ?console.log('action userLogin', context, obj)
? ? // 调用ajax请求去做登陆
? ? ?const res = await login(obj)
? ? // 在actions中,如果要修改state,还是要调用mutaions
? ? // context.commit('mutation名', 参数)
? ? ?context.commit('setToken', res.data)
? }
}
}
7.1在组件中调用action
async doLogin() {
? ? ?try {
? ? ? // // 1. 保存token到vuex
? ? ? // // 如何在组件调用带命名空间mutations
? ? ? // // this.$store.commit("命名空间/mutations名",载荷)
? ? ? // this.$store.commit('user/setToken', res.data)
? ? ? // 在组件中调用带命名空间的action
? ? ? ? ?
? ? ? ?await this.$store.dispatch('user/userLogin', this.loginForm)
? ? ? ?console.log('用户登录成功')
? ? } catch (err) {
? ? ? ?alert('用户登录,失败')
? ? ? ?console.log('用户登录,失败', err)
? ? }
? },
|