最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue-router vuex-oidc動(dòng)態(tài)路由實(shí)例及功能詳解

 更新時(shí)間:2023年11月22日 09:36:32   作者:charlotteeeeeee  
這篇文章主要為大家介紹了vue-router vuex-oidc動(dòng)態(tài)路由實(shí)例及功能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

功能描述

1:通過(guò)接口獲取當(dāng)前應(yīng)用的所有菜單基本信息及路由信息

2:vuex-oidc為可以檢測(cè)當(dāng)前是否獲取登錄信息,如果沒(méi)有,則會(huì)跳轉(zhuǎn)到登錄頁(yè)面

3:通過(guò)接口拿到的路由信息輔助指定到對(duì)應(yīng)vue頁(yè)面,完成頁(yè)面及路由的一一綁定

store.js

1:完成oidc相應(yīng)配置 詳細(xì)參見(jiàn)

2:建立儲(chǔ)存方法及獲取接口動(dòng)態(tài)菜單

import { createStore } from 'vuex'
import { vuexOidcCreateStoreModule } from 'vuex-oidc'
import gql from "graphql-tag";//graphQL語(yǔ)法標(biāo)簽,axios可刪除
import apolloProvider from "@/assets/js/apolloclient.js";//接口發(fā)起client 可按需換成axios
let g = window.Global;
let oidcSettings = {};
//window.Global會(huì)攜帶所有可用信息,此處為了方便本地調(diào)試加
//oidc相關(guān)配置參見(jiàn)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登錄配置相關(guān)信息,按需取舍
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: [], //非樹(shù)型結(jié)構(gòu)
        menulist: [], //樹(shù)型結(jié)構(gòu)
        asyncRoutestMark: false,
    },
    mutations: {
        // 單層級(jí)菜單,沒(méi)有父子結(jié)構(gòu),取決于接口返回信息,按需取舍
        setCanvasmenus(state, data) {
            state.canvasmenus = data
        },
        // 樹(shù)型菜單
        setMenulist(state, data) {
            state.menulist = data
        },
        // 標(biāo)記是否已經(jīng)發(fā)起過(guò)菜單獲取動(dòng)作,避免二次發(fā)起
        setAsyncRoutestMark(state, data) {
            state.asyncRoutestMark = data
        },
    },
    getters: {
        //本處做一次些菜單字段處理,可以按照自己項(xiàng)目做調(diào)整,可忽略
        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
        //簡(jiǎn)而言之,此處的action發(fā)起一個(gè)請(qǐng)求獲取動(dòng)態(tài)菜單信息
        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 相關(guān)配置,各種登錄狀態(tài)及相應(yīng)返回,詳細(xì)說(shuō)明見(jiàn)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";//將單層菜單整理層樹(shù)結(jié)構(gòu),可忽略
const publicRoutes = [{
        path: '/oidc-callback',//oidc登錄后回調(diào),可忽略
        name: 'OidcCallback',
        component: () =>
            import ('@/views/oidc/OidcCallback.vue')
    },
    {
        path: '/oidc-silent',//oidc靜態(tài)登錄,可忽略
        name: 'Oidcsilent',
        component: () =>
            import ('@/views/oidc/OidcRenew.vue')
    },
    {
        path: '/',
        name: "viewindex",
        component: () =>
            import ('@/views/view.vue'),//項(xiàng)目主入口模板
        meta: {
            requiresAuth: true
        },
    }
]
const router = createRouter({
    history: createWebHistory(contentPath),
    routes: publicRoutes, //靜態(tài)路由
});
// 動(dòng)態(tài)路由獲取到數(shù)據(jù)后加入routes
const routerData = (result) => {
    let currenRoutes = router.options.routes;
    // 獲取組件中所有vue文件
    let modules =
        import.meta.glob('../views/**/*.vue');
    if (result) {
        result.forEach((item, index) => {
            // has用于判斷當(dāng)前路由中是否已經(jīng)具有,避免重復(fù)
            let has = currenRoutes.some((it) => it.path == item.path);
            if (!has && item.routerpath) {
                //多語(yǔ)言
                let menutitlei18n = 'contact.menu.menu' + index; //多語(yǔ)言
                if (item.description && item.description.indexOf(',') >= 0) {
                    let mitems = item.description.split(',');
                    if (mitems[0]) {
                        menutitlei18n = 'contact.menu.' + mitems[0]
                    }
                }
                // 多語(yǔ)言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);
            }
        });
    }
};
// 動(dòng)態(tài)路由獲取
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,菜單不必再二次請(qǐng)求
                        store.commit('setCanvasmenus', res ? .data ? .canvasmenus);
                        navigationList = formSideTree(res ? .data ? .canvasmenus);
                    }
                })
                routerData(navigationList)
                store.commit('setAsyncRoutestMark', true) // 添加路由后更改標(biāo)識(shí)為true
                next({...to, replace: true }) //路由進(jìn)行重定向放行
            } else {
                next();
            }
        })
    } else {
        next();
    }
})
export default router

以上就是vue-router vuex-oidc動(dòng)態(tài)路由實(shí)例及功能詳解的詳細(xì)內(nèi)容,更多關(guān)于vue-router vuex-oidc動(dòng)態(tài)路由的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 在Vue3里使用scss實(shí)現(xiàn)簡(jiǎn)單的換膚功能

    在Vue3里使用scss實(shí)現(xiàn)簡(jiǎn)單的換膚功能

    這篇文章主要介紹了在Vue3里使用scss實(shí)現(xiàn)簡(jiǎn)單的換膚功能,主題色切換、亮色模式和暗黑模式切換、背景圖切換,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下
    2024-12-12
  • vue 開(kāi)發(fā)一個(gè)按鈕組件的示例代碼

    vue 開(kāi)發(fā)一個(gè)按鈕組件的示例代碼

    本篇文章主要介紹了vue 開(kāi)發(fā)一個(gè)按鈕組件的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • Vue之全局水印的實(shí)現(xiàn)示例

    Vue之全局水印的實(shí)現(xiàn)示例

    頁(yè)面水印大家或許都不陌生,本文主要介紹了Vue之全局水印的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • vue中使用@change的方法

    vue中使用@change的方法

    @change 是 Vue.js 中用于監(jiān)聽(tīng)表單元素值變化的事件處理器,很多組件有@change事件,那到底如何獲取到當(dāng)前的參數(shù)呢?本文給大家詳細(xì)講解,感興趣的朋友一起看看吧
    2023-11-11
  • 詳解如何在Vue Router中實(shí)現(xiàn)動(dòng)態(tài)路由匹配

    詳解如何在Vue Router中實(shí)現(xiàn)動(dòng)態(tài)路由匹配

    在構(gòu)建復(fù)雜的單頁(yè)面應(yīng)用程序(SPA)時(shí),動(dòng)態(tài)路由匹配是一項(xiàng)強(qiáng)大的功能,它允許我們根據(jù)URL中的參數(shù)動(dòng)態(tài)加載內(nèi)容,Vue Router 提供了動(dòng)態(tài)路由匹配的能力,使得我們可以根據(jù)不同的URL參數(shù)展示不同的組件或數(shù)據(jù),本文將介紹如何在Vue Router中實(shí)現(xiàn)動(dòng)態(tài)路由匹配
    2025-05-05
  • vue3+ts 兄弟組件之間傳值的實(shí)現(xiàn)

    vue3+ts 兄弟組件之間傳值的實(shí)現(xiàn)

    Vue3是一款流行的前端框架,它支持多種傳值方式,包括兄弟組件之間的傳值,本文主要介紹了vue3+ts 兄弟組件之間傳值的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-11-11
  • 詳解vue2父組件傳遞props異步數(shù)據(jù)到子組件的問(wèn)題

    詳解vue2父組件傳遞props異步數(shù)據(jù)到子組件的問(wèn)題

    本篇文章主要介紹了vue2父組件傳遞props異步數(shù)據(jù)到子組件的問(wèn)題,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • Vue3打包部署報(bào)錯(cuò)的解決方案

    Vue3打包部署報(bào)錯(cuò)的解決方案

    這篇文章主要介紹了Vue3打包部署報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • ElementUI 詳細(xì)分析DatePicker 日期選擇器實(shí)戰(zhàn)

    ElementUI 詳細(xì)分析DatePicker 日期選擇器實(shí)戰(zhàn)

    這篇文章主要介紹了ElementUI詳細(xì)分析DatePicker 日期選擇器實(shí)戰(zhàn)教程,本文通過(guò)實(shí)例代碼圖文介紹給大家講解的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • vue項(xiàng)目中Eslint校驗(yàn)代碼報(bào)錯(cuò)的解決方案

    vue項(xiàng)目中Eslint校驗(yàn)代碼報(bào)錯(cuò)的解決方案

    這篇文章主要介紹了vue項(xiàng)目中Eslint校驗(yàn)代碼報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04

最新評(píng)論

祁东县| 保靖县| 托里县| 西乌珠穆沁旗| 宝兴县| 周至县| 安图县| 大埔县| 射阳县| 清流县| 仁怀市| 绥棱县| 寿宁县| 南平市| 闵行区| 邵武市| 阳曲县| 福建省| 进贤县| 芮城县| 克什克腾旗| 宝山区| 屏边| 花莲市| 芜湖县| 柳林县| 伊吾县| 荔浦县| 吕梁市| 凤冈县| 黎平县| 旌德县| 库车县| 峡江县| 新和县| 方城县| 浙江省| 九寨沟县| 登封市| 蒙城县| 武宣县|