vue-router vuex-oidc动态路由实例及功能详解
作者:charlotteeeeeee
这篇文章主要为大家介绍了vue-router vuex-oidc动态路由实例及功能详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
功能描述
1:通过接口获取当前应用的所有菜单基本信息及路由信息
2:vuex-oidc为可以检测当前是否获取登录信息,如果没有,则会跳转到登录页面
3:通过接口拿到的路由信息辅助指定到对应vue页面,完成页面及路由的一一绑定
store.js
1:完成oidc相应配置 详细参见
2:建立储存方法及获取接口动态菜单
import { createStore } from 'vuex' import { vuexOidcCreateStoreModule } from 'vuex-oidc' import gql from "graphql-tag";//graphQL语法标签,axios可删除 import apolloProvider from "@/assets/js/apolloclient.js";//接口发起client 可按需换成axios let g = window.Global; let oidcSettings = {}; //window.Global会携带所有可用信息,此处为了方便本地调试加 //oidc相关配置参见1参考链接 if (!g) { g = { oauth2_uri: 'https://devel.ketanyun.cn/sso/oauth2', oauth2_logout_uri: 'https://devel.ketanyun.cn/sso/logout', }; } window.Global = {...g } let authority = g.oauth2_uri; let silentRedirectUri = (window.location.origin + g.contextpath + "/oidc-silent") //oidc登录配置相关信息,按需取舍 oidcSettings = { authority: authority, metadata: { issuer: authority, authorization_endpoint: authority + "/authorize", userinfo_endpoint: authority + "/userinfo", end_session_endpoint: g.oauth2_logout_uri + "?redirect_uri=" + window.location.origin + g.contextpath, jwks_uri: authority + "/jwks.json" }, clientId: g.client_id, redirectUri: window.location.origin + g.contextpath + "/oidc-callback", responseType: "id_token token", scope: "data openid ", automaticSilentRenew: true, silentRedirectUri: silentRedirectUri, silentRequestTimeout: 1000 }; export default createStore({ state: { canvasmenus: [], //非树型结构 menulist: [], //树型结构 asyncRoutestMark: false, }, mutations: { // 单层级菜单,没有父子结构,取决于接口返回信息,按需取舍 setCanvasmenus(state, data) { state.canvasmenus = data }, // 树型菜单 setMenulist(state, data) { state.menulist = data }, // 标记是否已经发起过菜单获取动作,避免二次发起 setAsyncRoutestMark(state, data) { state.asyncRoutestMark = data }, }, getters: { //本处做一次些菜单字段处理,可以按照自己项目做调整,可忽略 menuList(state) { let list = state.menulist ? (JSON.parse(JSON.stringify(state.menulist))) : []; list.map((item) => { const arr = item.path.split('/'); arr.splice(1, 1); item.routerpath = arr.join('/'); }) list = list && list.length ? list : ''; return list }, getterStorecanvasmenu(state) { return state.canvasmenus } }, actions: { //异步获取菜单信息,本处使用的granphQL-apolloclient,可以按需将其换成axios //简而言之,此处的action发起一个请求获取动态菜单信息 async getMenuList({ state }) { return apolloProvider.clients.builtinclient.query({ client: 'builtinclient', fetchPolicy: "no-cache", query: gql `query canvasmenus{ canvasmenus { parent name text description uri icon visible } }` }) } }, modules: { //oidc 相关配置,各种登录状态及相应返回,详细说明见1参考链接 oidcStore: vuexOidcCreateStoreModule( oidcSettings, { namespaced: true, dispatchEventsOnWindow: true }, { userLoaded: (user) => console.log('OIDC user is loaded:', user), userUnloaded: () => console.log('OIDC user is unloaded'), accessTokenExpiring: () => console.log('Access token will expire'), accessTokenExpired: () => console.log('Access token did expire'), silentRenewError: () => console.log('OIDC user is unloaded'), userSignedOut: () => console.log('OIDC user is signed out'), oidcError: (payload) => console.log('OIDC error', payload) } ) } })
router.js
import { createRouter, createWebHistory } from 'vue-router' import { vuexOidcCreateRouterMiddleware } from 'vuex-oidc' import store from "@/store/index";//引入store import { formSideTree } from "@/utils/index.js";//将单层菜单整理层树结构,可忽略 const publicRoutes = [{ path: '/oidc-callback',//oidc登录后回调,可忽略 name: 'OidcCallback', component: () => import ('@/views/oidc/OidcCallback.vue') }, { path: '/oidc-silent',//oidc静态登录,可忽略 name: 'Oidcsilent', component: () => import ('@/views/oidc/OidcRenew.vue') }, { path: '/', name: "viewindex", component: () => import ('@/views/view.vue'),//项目主入口模板 meta: { requiresAuth: true }, } ] const router = createRouter({ history: createWebHistory(contentPath), routes: publicRoutes, //静态路由 }); // 动态路由获取到数据后加入routes const routerData = (result) => { let currenRoutes = router.options.routes; // 获取组件中所有vue文件 let modules = import.meta.glob('../views/**/*.vue'); if (result) { result.forEach((item, index) => { // has用于判断当前路由中是否已经具有,避免重复 let has = currenRoutes.some((it) => it.path == item.path); if (!has && item.routerpath) { //多语言 let menutitlei18n = 'contact.menu.menu' + index; //多语言 if (item.description && item.description.indexOf(',') >= 0) { let mitems = item.description.split(','); if (mitems[0]) { menutitlei18n = 'contact.menu.' + mitems[0] } } // 多语言end // 仅作为viewindex子组件 router.addRoute("viewindex", { path: `${item.routerpath}`, name: item.name, meta: { title: item.name, requiresAuth: true, menutitlei18n, }, component: modules[`../views${item.path}.vue`] }); } if (item.children && item.children.length) { routerData(item.children); } }); } }; // 动态路由获取 router.beforeEach((to, from, next) => { if (!(to.matched && to.matched.length)) { if (to.path !== '/') { next({ path: '/' }); return } } const requiresAuth = to.matched.some(record => record.meta.requiresAuth); if (requiresAuth) { vuexOidcCreateRouterMiddleware(store, 'oidcStore')(to, from, async() => { if (!store.state.asyncRoutestMark) { //是否已完成路由添加 let navigationList = []; store.commit('setCanvasmenus', []) await store.dispatch('getMenuList').then((res) => { if (res ? .data ? .canvasmenus) { res ? .data ? .canvasmenus ? .map((item) => { if (item.uri) { if (item.uri && item.uri.split("vue://")[1] && item.uri.split("vue://")[1].indexOf("@") >= 0) { item.path = item.uri.split("vue://")[1].split("@")[0]; let arr = item.path.split('/'); arr.splice(1, 1); item.routerpath = arr.join('/') } } }); //存入store,菜单不必再二次请求 store.commit('setCanvasmenus', res ? .data ? .canvasmenus); navigationList = formSideTree(res ? .data ? .canvasmenus); } }) routerData(navigationList) store.commit('setAsyncRoutestMark', true) // 添加路由后更改标识为true next({...to, replace: true }) //路由进行重定向放行 } else { next(); } }) } else { next(); } }) export default router
以上就是vue-router vuex-oidc动态路由实例及功能详解的详细内容,更多关于vue-router vuex-oidc动态路由的资料请关注脚本之家其它相关文章!