1.布局分析
登录组件 login.vue 布局要点如下:
- el-form 容器,包含 username 和 password 两个 el-form-item,el-form 主要属性:
- model 为 loginForm
- rules 为 loginRules
- password 使用了 el-tooltip 提示,当用户打开大小写时,会进行提示,主要属性:
- manual:手动控制模式,设置为 true 后,mouseenter 和 mouseleave 事件将不会生效
- placement:提示出现的位置
- password 对应的 el-input 主要属性:
@keyup.native="checkCapslock"
键盘按键时绑定 checkCapslock 事件@keyup.enter.native="handleLogin"
监听键盘 enter 按下后的事件
这里绑定
@keyup
事件时需要添加.native
修饰符,这是因为我们的事件绑定在 el-input 组件上,所以如果不添加.native
修饰符,事件将无法绑定到原生的 input 标签上
- 包含一个 el-button,点击时调用
handleLogin
方法,并触发 loading 效果
2.checkCapslock 方法
checkCapslock
方法的主要用途是监听用户键盘输入,显示提示文字的判断逻辑如下:
- 按住 shift 时输入小写字符
- 未按 shift 时输入大写字符
当按下 CapsLock 按键时,如果按下后是小写模式,则会立即消除提示文字
checkCapslock({ shiftKey, key } = {}) { if (key && key.length === 1) { if (shiftKey && (key >= 'a' && key <= 'z') || !shiftKey && (key >= 'A' && key <= 'Z')) { this.capsTooltip = true } else { this.capsTooltip = false } } if (key === 'CapsLock' && this.capsTooltip === true) { this.capsTooltip = false } }
3.handleLogin 方法
handleLogin
方法处理流程如下:
- 调用 el-form 的
validate
方法对 rules 进行验证; - 如果验证通过,则会调用 vuex 的
user/login
action 进行登录验证; - 登录验证通过后,会重定向到 redirect 路由,如果 redirect 路由不存在,则直接重定向到
/
路由
这里需要注意:由于 vuex 中的 user 指定了 namespaced 为 true,所以 dispatch 时需要加上 namespace,否则将无法调用 vuex 中的 action
handleLogin() { this.$refs.loginForm.validate(valid => { if (valid) { this.loading = true this.$store.dispatch('user/login', this.loginForm) .then(() => { this.$router.push({ path: this.redirect || '/', query: this.otherQuery }) this.loading = false }) .catch(() => { this.loading = false }) } else { console.log('error submit!!') return false } }) }
4.user/login 方法
user/login
方法调用了 login API,传入 username 和 password 参数,请求成功后会从 response 中获取 token,然后将 token 保存到 Cookie 中,之后返回。如果请求失败,将调用 reject 方法,交由我们自定义的 request 模块来处理异常
login({ commit }, userInfo) { const { username, password } = userInfo return new Promise((resolve, reject) => { login({ username: username.trim(), password: password }).then(response => { const { data } = response commit('SET_TOKEN', data.token) setToken(data.token) resolve() }).catch(error => { reject(error) }) }) }
login API 的方法如下:
import request from '@/utils/request' export function login(data) { return request({ url: '/user/login', method: 'post', data }) }
这里使用 request 方法,它是一个基于 axios 封装的库,目前我们的 /user/login
接口是通过 mock 实现的,用户数据位于 /mock/user.js