vue-element-admin下载到登录的一些坑
快速上手
官方文档:https://panjiachen.github.io/vue-element-admin-site/zh/guide/
启动项目
拉取代码之后进行npm i 安装
ctrl -c 之后
执行命令:git config --global url.“https://”.insteadOf git:// 重新 npm i 成功! npm run dev 启动成功
依赖下载成功截图
另外npm i之后也可能会发现其他的报错
具体哪些就不一一列举了,我这边node版本 v10.20.0 ,npm版本6.14.4
这里列举 是因为之前有报错发现要升级npm版本下载依赖,有个core.js很难下载。
下载固定npm指令: npm install npm@6.14.4 -g
node的话nvm随便下载就好了
启动成功
登录流程解析
1.目录结构
重要文件
permission.js
登录流程中,src/permission.js是最重要的环节,这个文件是路由的全局钩子(beforeEach和afterEach),全局钩子的意思就是每次跳转的时候可以根据情况进行拦截,不让他跳转。使用场景就是有些页面需要登录才能访问,这时候就可以在beforeEach中校验用户登录状态来进行拦截。
utils/auth.js
设置token到cookie中的操作封装。
router
有关路由的一些设置
登录流程解析
1.登录页面:view/login/index.vue
点击登录按钮后,触发handleLogin方法,利用validate进行表单验证,如果验证通过,调用user/login方法传递表单里的数据,根据.then回调执行this.$router.push方法,这个方法用于跟踪:我是从哪里跳到/login页面的,登录后我就返回哪里。
2./user/login方法:src/store/modules/user.js
这个方法主要做了以下工作:登录验证,登录成功后,分别把token保存在vuex和cookie中。
3.permission.js :src/permission.js
router.beforeEach(async(to, from, next) => { // 从cookie中取得token const hasToken = getToken() // 如果有token 也就是已经登陆的情况下 if (hasToken) { // 并且要前往的路径是'/login' 则返回 '/' if (to.path === '/login') { next({ path: '/' }) } else { // 从store中取得用户的 roles, 也就是用户的权限 并且用户的权限数组必须有一个以上 const hasRoles = store.getters.roles && store.getters.roles.length > 0 // 有权限则直接进入 if (hasRoles) { next() } else { // 没有权限的话 try { // 获取用户信息 const { roles } = await store.dispatch('user/getInfo') // 生成可访问路由 const accessRoutes = await store.dispatch('permission/generateRoutes', roles) // 将可访问路由添加到路由上 router.addRoutes(accessRoutes) // 进入路由 next({ ...to, replace: true }) } catch (error) { // 如果出现异常 清空路由 await store.dispatch('user/resetToken') // Message提示错误 Message.error(error || 'Has Error') // 跳到login页面重新登陆 next(`/login?redirect=${to.path}`) } } } } else { // 没有token 也就是没有登陆的情况下 // 判断是否是白名单(也就是说不需要登陆就可以访问的路由) if (whiteList.indexOf(to.path) !== -1) { next() } else { // 其他的一律给我跳到login页面 老老实实的进行登陆 next(`/login?redirect=${to.path}`) NProgress.done() } } })
利用beforeEach进行访问拦截,如果没登录,跳转到登录页面进行登录。
4.user/getInfo:src/store/modules/user.js
getInfo用于获取用户信息并保存到vuex中,后面是一堆的数据校验。
5.permission/generateRoutes:src/store/modules/permission.js
// 判断是否有权限 function hasPermission(roles, route) { if (route.meta && route.meta.roles) { // roles.some => Array.some 相当于是只要有一个满足就为true // 判断用户的权限于当前路由访问所需要的权限是否有一个满足 // 比如说用户权限为 ['one','two'] 当前路由访问所需要权限为 ['two','three'] 那么就说明当前用户可以访问这个路由 return roles.some(role => route.meta.roles.includes(role)) } else { // 默认是可访问的 return true } } // 生成可访问路由 export function filterAsyncRoutes(routes, roles) { const res = [] routes.forEach(route => { const tmp = { ...route } // 判断当前路由是否可以访问 if (hasPermission(roles, tmp)) { // 如果当前路由还有子路由 if (tmp.children) { // 进行递归处理 tmp.children = filterAsyncRoutes(tmp.children, roles) } // 将可访问路由放入数组中 res.push(tmp) } }) // 返回 return res } // 为什么要写这里呢,因为后面的Sidebar组件与这个环环相扣 const mutations = { SET_ROUTES: (state, routes) => { // 添加的路由 state.addRoutes = routes // 将vuex中的路由进行更新 state.routes = constantRoutes.concat(routes) } } const actions = { generateRoutes({ commit }, roles) { return new Promise(resolve => { let accessedRoutes // 如果roles包含 'admin' 直接可以全部访问 if (roles.includes('admin')) { accessedRoutes = asyncRoutes || [] } else { // 利用 filterAsyncRoutes 过滤出可访问的路由 accessedRoutes = filterAsyncRoutes(asyncRoutes, roles) } // 保存可访问的路由到store中 commit('SET_ROUTES', accessedRoutes) // 将可访问路由返回 resolve(accessedRoutes) }) } }
generateRoutes就是根据得到的用户权限生成可以访问的路由。
动态路由实现
router.addRoutes(accessRoutes)
思维流程图
替换接口实现登录
第一步替换接口,这里有三个接口,建议一个一个改
第二步,将mock数据注释掉
第三步,修改环境配置
第四步,启动项目之后查看eg:登录接口返回数据的格式
如果你不想改那就必须与后端协商将接口返回数据格式与原有接口数据结构返回一模一样(特别重要的一点),如果一模一样点击登录就会跳转。(成功)
如果接口已经写好,那就必须修改以下的文件,格式对不上不仅影响功能,控制台也会报错
格式与原有格式返回不同需要修改的文件
1.切入点,先找到登录接口,所以从user/login开始查找
返回res相关的登录,获取用户信息,退出登录接口,commit方法传的值很可能传错,token的值都需要控制台输出一下判断正确,以及逻辑传参是否丢失
这里是修改之后的,包括其他相关接口返回都需要修改
request.js响应code码根据接口返回情况进行判断
替换接口遇到的问题
报错原因:
项目中使用的是Element UI消息提示Message:import { Message } from ‘element-ui’;
请求响应拦截器中err处理的代码错误:
Message.error(response.data.data|| "出现错误,请稍后再试");//写法错误,
解决方法:
Message.error({ message: response.data.data || "出现错误,请稍后再试" }) 或 Message({ type:'error', message: response.data.data || "出现错误,请稍后再试" })
如果改完之后发现还报错,也可能是改完登录接口,没改用户信息接口,用户信息接口(或是其他)报错引发的