最后
为了帮助大家更好的了解前端,特别整理了《前端工程师面试手册》电子稿文件。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
router.addRoutes(res)
next({ ...to, replace: true })
})
} catch (error) {
await store.dispatch('user/resetToken')
Message.error(error || 'Has Error')
next(`/login?redirect=${to.path}`)
NProgress.done()
}
}
}
} else {
/* has no token*/
if (whiteList.indexOf(to.path) !== -1) {
next()
} else {
next(/login?redirect=${to.path}
)
NProgress.done()
}
}
})
getInfo({ commit, state }){
return new Promise((resolve, reject) => {
const { roles } = JSON.parse(getUser())
commit(“SET_ROLES”, roles)
resolve(roles)
})
},
## 问题二:addRouters()不生效
>
> 执行完addRouters()后,我查看了store里的routes,已经有将动态路由添加进去,但是菜单中还是没有显示
>
>
>
>
> 查看了/layout/components/Sidebar/index.vue,发现使用的是this.
>
>
>
>
> r
>
>
> o
>
>
> u
>
>
> t
>
>
> e
>
>
> r
>
>
> .
>
>
> o
>
>
> p
>
>
> t
>
>
> i
>
>
> o
>
>
> n
>
>
> s
>
>
> .
>
>
> r
>
>
> o
>
>
> u
>
>
> t
>
>
> e
>
>
> s
>
>
> 而
>
>
> 不
>
>
> 是
>
>
> s
>
>
> t
>
>
> o
>
>
> r
>
>
> e
>
>
> 中
>
>
> 的
>
>
> ,
>
>
> 所
>
>
> 以
>
>
> 我
>
>
> 们
>
>
> 需
>
>
> 要
>
>
> 在
>
>
> a
>
>
> d
>
>
> d
>
>
> R
>
>
> o
>
>
> u
>
>
> t
>
>
> e
>
>
> r
>
>
> s
>
>
> (
>
>
> )
>
>
> 后
>
>
> 也
>
>
> 修
>
>
> 改
>
>
> t
>
>
> h
>
>
> i
>
>
> s
>
>
> .
>
>
>
> router.options.routes而不是store中的,所以我们需要在addRouters()后也修改this.
>
>
> router.options.routes而不是store中的,所以我们需要在addRouters()后也修改this.router.options.routes的值,或者直接修改下面routes()方法,直接使用store中的routes
>
>
>
routes() {
return this.$router.options.routes
}
**修改后的permission.js**
const roles = await store.dispatch(‘user/getInfo’)
await store.dispatch(‘permission/generateRoutes’, roles).then(res => {
router.addRoutes(res)
router.options.routes = store.getters.routes
next({ …to, replace: true })
})
## 最终版,所有相关文件
* router/index.js
import Vue from ‘vue’
import Router from ‘vue-router’
import Layout from ‘@/layout’
Vue.use(Router)
export const constantRoutes = [
{
path: “”,
redirect: ‘/portal’,
},
{
path: ‘/login’,
component: () => import(‘@/views/login/index’),
},
{
path: ‘/404’,
component: () => import(‘@/views/404’),
},
{
path: ‘/portal’,
component: () => import(‘@/views/portal/index’),
},
{
path: ‘/’,
component: Layout,
redirect: ‘/dashboard’,
children: [{
path: ‘dashboard’,
name: ‘Dashboard’,
component: () =>
import (‘@/views/dashboard/index’),
meta: { title: ‘资源认证平台’, affix: true, icon: ‘dashboard’ }
}]
},
{
path: ‘/user’,
component: Layout,
redirect: ‘/user’,
children: [{
path: ‘user’,
name: ‘User’,
component: () =>
import (‘@/views/user/index’),
meta: { title: ‘用户管理’, affix: true, icon: ‘user’, }
}]
}
// 404 page must be placed at the end !!!
]
export const asyncRoutes = [
{
path: ‘/application’,
component: Layout,
redirect: ‘/application’,
children: [{
path: ‘application’,
name: ‘Application’,
component: () =>
import (‘@/views/application/index’),
meta: { title: ‘应用管理’, affix: true, icon: ‘table’, roles: [‘system’] }
}]
},
{ path: ‘*’, redirect: ‘/404’, hidden: true }
]
const createRouter = () => new Router({
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes
})
const router = createRouter()
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
export default router
* store/modules/permission.js
// 首先,从index.js中引入已经定义过的2个router数组
import { asyncRoutes, constantRoutes } from ‘@/router’
// 全局变量state,routes和addRoutes数组
const state = {
routes: [],
addRoutes: []
}
// mutations 是唯一可以更改state的函数,使用SET_ROUTES定义更改方法,SET_ROUTES(state, routes)的入参routes赋值给addRoutes数组,将constantRoutes静态路由数组增加routes;
const mutations = {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
}
}
// vue中store状态管理,通过actions调用 mutations 中封装的方法来实现对于state更改,
// 这里是vue-element-admin中动态路由的主要判断逻辑发生地方,首先判定用户角色是否包含admin(可能多角色),是则将所有asyncRoutes 加入到constantRoutes,若用户角色没有包含admin,则调用filterAsyncRoutes函数,递归地判定asyncRoutes.roles属性是否有该角色,即是否有权限,将有权限的router赋值accessedRoutes 后加入到constantRoutes;
const actions = {
generateRoutes({ commit }, roles) {
return new Promise(resolve => {
let accessedRoutes
if (roles.includes(‘system’)) {
accessedRoutes = asyncRoutes || []
} else {
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
}
commit(‘SET_ROUTES’, accessedRoutes)
resolve(accessedRoutes)
})
}
}
//-----------------
// 两个上面使用的方法
function hasPermission(roles, route) {
if (route.meta && route.meta.roles) {
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
}
export default {
namespaced: true,
state,
mutations,
actions
}
* src/permission.js
import router from ‘./router’
import store from ‘./store’
import { Message } from ‘element-ui’
import NProgress from ‘nprogress’ // progress bar
import ‘nprogress/nprogress.css’ // progress bar style
import { getToken } from ‘@/utils/auth’ // get token from cookie
import getPageTitle from ‘@/utils/get-page-title’
NProgress.configure({ showSpinner: false }) // NProgress Configuration
const whiteList = [‘/login’] // no redirect whitelist
router.beforeEach(async(to, from, next) => {
NProgress.start()
document.title = getPageTitle(to.meta.title)
const hasToken = getToken()[‘Authorization’]
if (hasToken) {
if (to.path === ‘/login’) {
next({ path: ‘/’ })
NProgress.done()
} else {
const hasRoles = store.getters.roles && store.getters.roles.length > 0
if(hasRoles){
next()
}else{
try {
const roles = await store.dispatch(‘user/getInfo’)
await store.dispatch(‘permission/generateRoutes’, roles).then(res => {
router.addRoutes(res)
router.options.routes = store.getters.routes
next({ …to, replace: true })
})
} catch (error) {
await store.dispatch(‘user/resetToken’)
Message.error(error || ‘Has Error’)
next(/login?redirect=${to.path}
)
NProgress.done()
}
}
}
} else {
/* has no token*/
if (whiteList.indexOf(to.path) !== -1) {
next()
} else {
next(/login?redirect=${to.path}
)
NProgress.done()
}
}
})
最后
整理面试题,不是让大家去只刷面试题,而是熟悉目前实际面试中常见的考察方式和知识点,做到心中有数,也可以用来自查及完善知识体系。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
《前端基础面试题》,《前端校招面试题精编解析大全》,《前端面试题宝典》,《前端面试题:常用算法》
t.indexOf(to.path) !== -1) {
next()
} else {
next(/login?redirect=${to.path}
)
NProgress.done()
}
}
})
最后
整理面试题,不是让大家去只刷面试题,而是熟悉目前实际面试中常见的考察方式和知识点,做到心中有数,也可以用来自查及完善知识体系。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
《前端基础面试题》,《前端校招面试题精编解析大全》,《前端面试题宝典》,《前端面试题:常用算法》
[外链图片转存中…(img-DN4u3xPJ-1715830099312)]
[外链图片转存中…(img-QeSjeHZw-1715830099313)]
[外链图片转存中…(img-W9XU9OEQ-1715830099313)]