https://gitee.com/elunez/eladmin-web/blob/master/src/views/login.vue
src/views/login.vue的代码很好理解,很快我们就找到了提交的入口:handleLogin
handleLogin() {
this.$refs.loginForm.validate(valid => {
const user = {
username: this.loginForm.username,
password: this.loginForm.password,
rememberMe: this.loginForm.rememberMe,
code: this.loginForm.code,
uuid: this.loginForm.uuid
}
if (user.password !== this.cookiePass) {
user.password = encrypt(user.password)
}
if (valid) {
this.loading = true
if (user.rememberMe) {
Cookies.set('username', user.username, { expires: Config.passCookieExpires })
Cookies.set('password', user.password, { expires: Config.passCookieExpires })
Cookies.set('rememberMe', user.rememberMe, { expires: Config.passCookieExpires })
} else {
Cookies.remove('username')
Cookies.remove('password')
Cookies.remove('rememberMe')
}
this.$store.dispatch('Login', user).then(() => {
this.loading = false
this.$router.push({ path: this.redirect || '/' })
}).catch(() => {
this.loading = false
this.getCode()
})
} else {
console.log('error submit!!')
return false
}
})
}
在this.$store.dispatch('Login', user) 之前的代码我们都看的很清楚,都是顺序执行,没有什么跳跃,但是突然到了这个dispatch,彻底迷路了,这是个什么鬼,调用了哪里的代码呢,也不说一下。
看到store于是去store里面找,终于在store/modules/user.js里面找到了 https://gitee.com/elunez/eladmin-web/blob/master/src/store/modules/user.js
说实话这样的调用实在很不厚道,这就是我们迷乱的原因,程序的执行没有明确的指向,仅凭一个字符串就让我们到处找。
那么这个actions到底是怎么一回事呢。通过官方文档我们知道几个重要的信息 https://vuex.vuejs.org/zh/guide/actions.html
Action 通过 store.dispatch
方法触发:
他们都是vuex的概念。vuex又是什么?你可以把它理解一个全局变量的操作类,你只能通过这个操作类来操作全局变量,这样才不至于满世界找到底是谁不小心改变了全局变量。集中改变的好处,就是能够写工具来监控变量的改变,你想别人都调用你的方法来执行操作,你就可以在你的代码里面加入berore和after来做更多的处理了。
function changeA(parameter){
before();
a=parameter
after();
}
那handleLogin到底做了什么?
1.它调用了login这个api,import {login, getInfo, logout} from '@/api/login',很显然这个接口传入用户名密码并返回了用户相关的信息。https://gitee.com/elunez/eladmin-web/blob/master/src/api/login.js
2.它保存了token,在import {getToken, setToken, removeToken} from '@/utils/auth' 这个里面它把token保存到了cookie里面
https://gitee.com/elunez/eladmin-web/blob/master/src/utils/auth.js
3.它将token保存为了vuex的全局变量
4.它设置了用户的基本信息到全局变量 state.user,并且保存了角色信息。
state: {
token: getToken(),
user: {},
roles: [],
// 第一次加载菜单时用到
loadMenus: false
}
Login({commit}, userInfo) {
const rememberMe = userInfo.rememberMe
return new Promise((resolve, reject) => {
login(userInfo.username, userInfo.password, userInfo.code, userInfo.uuid).then(res => {
setToken(res._sessionToken, rememberMe)
commit('SET_TOKEN', res._sessionToken)
setUserInfo(res, commit)
// 第一次加载菜单时用到, 具体见 src 目录下的 permission.js
commit('SET_LOAD_MENUS', true)
resolve()
}).catch(error => {
reject(error)
})
})
}
this.$store.dispatch('Login', user) 第一个'Login'这个是actions的名字,第二个user,这个是参数,一段代码的引用仅仅通过一个字符串来关联,而且这个字符串貌似是全局属性的,那么如果我随便写在一个地方,这不是成心让人迷路吗,这样的设计令人怀疑。
login提交了之后程序又去了哪里呢?
this.$store.dispatch('Login', user).then(() => {
this.loading = false
this.$router.push({ path: this.redirect || '/' })
}).catch(() => {
this.loading = false
this.getCode()
})
我们看到程序的路由指向了,this.$router.push({ path: this.redirect || '/' }),而this.redirect在login.vue里面定义为undefined,所以成功之后用户跳转到了"/",我们又要去看router/index.js里面对这个url的拦截了。