一:文件结构讲解
1.文件价格
package.json文件防止模板所需要的各种依赖,npm install 就是安装这些
index.js文件放置的是路由
main.js文件放置初始化,加载所需要的插件
public下index.html 时一个模板文件,作用是生成项目的入口文件
二:登录模块
登录逻辑:当用户填写完账号密码后向服务端验证是否正确,验证通过后,服务端会返回一个token,拿到token后(可将token存到cookie中,保证页面刷新后可以记住用户登录状态),前端会根据token拉取一个 user_info接口来获取用户详情信息(如用户权限,用户名等)。
权限验证:通过token获取用户对应的 role,动态根据用户的 role 算出其对应有权限的路由,通过 router.addRoutes 动态挂载这些路由。
首先看一下登录的具体流程:
1、输入账号密码后,点击登录,触发click事件
//登录
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
}
})
},
可以看出,点击过登录按钮后,调用了store文件夹里的一个方法,名叫login
2、store里面的login方法
/ user login
login({commit}, userInfo) {
const {username, password} = userInfo
return new Promise((resolve, reject) => {
login({loginName: username.trim(), passwd: password}).then(response => {
const data = response
commit('SET_TOKEN', data)
setToken(data)
resolve()
}).catch(error => {
reject(error)
})
})
},
此处第一个login是$store中的方法,第二个login方法是,api里的login方法,用来调用接口的
3、api中的login方法
import request from '@/utils/request'
export function login(data) {
return request({
url: uapPath + '/user/launcher',
method: 'post',
data
})
}
此处是api中的login方法,上面import引入了utils下的request,本质上是它调用了request.js,request.js是对axios进行了封装(统一请求拦截和响应拦截),用来请求后台接口的,如果这个接口请求成功,则回到login.vue页面中的.then()方法路由跳转到登录页。
4、request.js
可以看到在这个请求中配置了baseURL,这个值是读取的项目根目录下的.env.development(开发环境)或者.evn.production(生产环境)文件中配置的VUE_APP_BASE_API值。
5、权限控制
permission主要负责全局路由守卫和登录判断,可以理解为一个拦截器,下面来看一下具体的逻辑:
每一步都添加了注释
从代码上来看,主要分两种情况:有token和无token
有token:再看看是不是去登录页的,登录页肯定不能拦截的,如果是登录页就直接放行。如果不是登录页,就要看看本地有没有用户信息,看看cookie中有没有用户信息(不一定是token,也可能是localstorage)。如果有用户信息,放行。如果没有用户信息,就调用接口去获取登录信息,router.addRoutes涉及到了动态添加路由。获取到用户信息后放行。如果在获取用户信息的过程中报错,则回到登录页。
无token:先看看用户要进入的页面是不是在白名单内,一般登录、注册、忘记密码都是在白名单内的,这些页面,在无token的情况下也是直接放行。如果不在白名单内,则回到登录页。