17-使用前置导航守卫判断用户登录后刷新情况

首先加一下菜单的两个属性

json 复制代码
:unique-opened="true" // 是否只保持一个子菜单的展开
:router="true" // 是否启用 vue-router 模式。 启用该模式会在激活导航时以 index 作为 path 进行路由跳转 使用 default-active 来设置加载时的激活项。
html 复制代码
<template>
    <div class="home-container">
        <div class="home-header">头部</div>
        <div class="home-menu">
            <el-menu
                active-text-color="#ffd04b"
                background-color="#545c64"
                class="el-menu-vertical-demo"
                default-active="2"
                text-color="#fff"
                :unique-opened="true"
                :router="true"
            >
                <el-sub-menu v-for="menu in newMenus" :index="menu.id">
                    <template #title>
                        <span>{{ menu.title }}</span>
                    </template>
                    <template v-for="submenu in menu.children">
                        <el-menu-item v-if="submenu.hidden === 0" :index="submenu.id">{{ submenu.title }}</el-menu-item>
                    </template>
                </el-sub-menu>
            </el-menu>
        </div>
        <div class="home-content">右侧内容</div>
    </div>
</template>

<script lang='ts' setup>
/**
{
    id: {
        title: "一级菜单",
        children: [
            {title: "二级菜单"},
            {title: "二级菜单"},
            {title: "二级菜单"},
            {title: "二级菜单"},
        ]
    }
}
 * */ 
import { } from 'vue'
import { useStore } from 'vuex'

interface MenuObj {
    id: string
    title: string
    parentId: string
    hidden: 0 | 1
    children?: MenuObj[]
}

interface NewMenus {
    [key: string]: MenuObj
}

const store = useStore();
const newMenus: NewMenus = store.getters.getNewMenus;
console.log('newMenus---------home-----------', newMenus)
</script>

<style lang='less' scoped>
.home-container {
    position: relative;
    height: 100%;

    .home-header {
        height: 70px;
        background-color: goldenrod;
    }

    .home-menu {
        position: absolute;
        top: 70px;
        left: 0;
        bottom: 0;
        width: 250px;
        background-color: #a37676;
    }

    .home-content {
        position: absolute;
        top: 70px;
        right: 0;
        left: 250px;
        bottom: 0;
        background-color: skyblue;
    }
}
</style>

然后等价路由导航守卫

vuex 添加默认导出

ts 复制代码
import { createStore } from 'vuex'
import { type App } from 'vue'

interface MenuObj {
    id: string
    parentId: string
    children?: MenuObj[]
}

interface State {
    menus: MenuObj[]
}

interface NewMenus {
    [key: string]: Partial<MenuObj>
}

const store = createStore<State>({
    state() {
        return {
            menus: []
        }
    },
    getters: {
        getNewMenus(state) {
            const newMenus: NewMenus = {}
            const menus = state.menus

            for (let i = 0; i < menus.length; i++) {
                const menu = menus[i] as MenuObj
                if (menu.parentId === '0') {
                    // 一级菜单:初始化 children 为空数组,方便后续 push
                    newMenus[menu.id] = {
                        ...menus[i],
                        children: newMenus[menu.id]?.children || []
                    }
                } else {
                    // 子级菜单:根据 parentId 找到对应的父级
                    const parentId = menu.parentId
                    newMenus[parentId] = newMenus[parentId] || {}
                    newMenus[parentId].children = newMenus[parentId].children || []
                    newMenus[parentId].children.push(menu)
                }
            }
            console.log('newMenus--------------------', newMenus)
            return newMenus;
        }
    },
    mutations: {
        updateMenus(state, menus) {
            console.log('updateMenus--->', state, menus)
            state.menus = menus
        }
    },
    actions: {},
    modules: {}
})

export const initStore = (app: App<Element>) => {
    app.use(store)
}

export default store

路由添加守卫

ts 复制代码
import {
    createRouter,
    createWebHashHistory,
    type RouteRecordRaw
} from 'vue-router'
import { type App } from 'vue'
import store from '../store'
import Cookie from 'js-cookie'

const routes: RouteRecordRaw[] = [
    {
        path: '/',
        redirect: '/login'
    },
    {
        path: '/login',
        name: 'login',
        component: () => import('../views/login/login.vue')
    },
    {
        path: '/home',
        name: 'home',
        component: () => import('../views/home/home.vue')
    }
]

const router = createRouter({
    history: createWebHashHistory(),
    routes // 路由配置
})

// 前置导航守卫
router.beforeEach((to, from, next) => {
    // 1、token && vuex里面的 menus 为空
    const token = Cookie.get('token')
    console.log(store)
    if(token && store.state.menus.length === 0) {
        console.log('menus为空')
    }
})

export const initRouter = (app: App<Element>) => {
    app.use(router)
}
相关推荐
RuoyiOffice12 小时前
SpringBoot+Vue3 节日主题换肤实战:一条参数换全站配色,节后自动还原
spring boot·vue3·spring boot 3·vben admin·ruoyi office·节日主题·换肤方案
RuoyiOffice3 天前
SpringBoot3+Vue3 流程抄送已读:打开详情消红点,待办与知会怎么分开
spring boot·vue3·flowable·spring boot 3·ruoyi office·流程抄送·已读回执
志尊宝3 天前
Vue3 零基础每日笔记(038):亲手封装 useDebounceFn 与 useThrottleFn——高频事件的流量阀
前端·javascript·vue·html·vue3
志尊宝4 天前
Vue3 零基础每日笔记(043):defineModel 与 defineExpose 的 TS 用法——3.4+ 新 API 进阶
前端·javascript·vue·html·vue3
RuoyiOffice5 天前
SpringBoot3+Vue3+Flowable 企业审批平台全链路:从表单设计、节点权限到移动审批怎么落地
spring boot·vue3·uniapp·springboot3·flowable·审批系统·ruoyi office
RuoyiOffice5 天前
SpringBoot3+Vue3 企业级管理平台架构:多租户、RBAC、数据权限、工作流与微服务一次讲透
spring boot·vue3·springboot3·rbac·多租户·数据权限·ruoyi office
Bs_MoneyMagnet5 天前
基于springboot+vue的个人健康管理系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·vue3·springboot3·计算机毕业设计
志尊宝5 天前
Vue3 零基础每日笔记(026):emit 子传父——defineEmits 与事件校验
前端·javascript·html·vue3
RuoyiOffice5 天前
SpringBoot3+Vue3 库存盘点:账面和实盘对不上,差异单怎么走审批再调账
spring boot·vue3·erp·spring boot 3·库存盘点·盘盈盘亏
RuoyiOffice6 天前
SpringBoot3+PaddleOCR 发票识别:不接云端大模型,本地飞桨怎么把专票读进进项单
spring boot·vue3·飞桨·paddleocr·spring boot 3·发票ocr·进项发票