You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3+Pinia实现登录后无需刷新动态切换导航栏菜单

问题解决:导航栏实时更新与逻辑优化

1. 实时更新问题修复

当前登录后导航栏不实时更新的核心原因是:Pinia Store 中的 user 响应式变量未在登录时同步更新,仅依赖 localStorage 初始化,导致计算属性 username 无法感知登录状态变化。

修改 loginStore.ts

在登录成功后,除了写入 localStorage,必须同步更新 user 响应式变量:

import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
import LoginService from '@/services/LoginService'

export const useLoginStore = defineStore('login', () => {
  const user = ref(localStorage.getItem('user'))
  
  // 增加trim处理,避免用户名前后空格导致判断错误
  const username = computed(() => user.value?.trim())

  const login = async (username: string, password: string): Promise<void> => {
    try {
      // ... 登录API调用代码 ...
      // 同步更新localStorage和Store状态
      localStorage.setItem('user', username)
      user.value = username // 关键:触发响应式更新
    } catch (err) {
      throw err
    } finally {
      // ... 后续清理代码 ...
    }
  }

  // 可选:添加登出函数,确保状态同步清理
  const logout = () => {
    localStorage.removeItem('user')
    user.value = null
  }

  return {
    user, username, login, logout
  }
})

2. 导航栏逻辑优化

原代码的多重 v-if/v-else-if 逻辑冗余且易出错,通过响应式判断函数统一处理菜单可见性规则,大幅提升代码可读性和可维护性:

修改 Navbar.vue

<template>
  <!-- 假设外层循环为v-for="value in pageList" -->
  <v-list-item 
    v-for="value in pageList" 
    :key="value" 
    v-if="isMenuItemVisible(value)"
  >
    <p class="text-uppercase font-weight-bold text-caption">
      {{ $t(`pages.${value}`) }} 
    </p>
  </v-list-item>
</template>

<script setup>
import { useLoginStore } from '@/stores/loginStore'
import { storeToRefs } from 'pinia'
import { computed } from 'vue'

const store = useLoginStore()
const { username } = storeToRefs(store)

// 统一判断菜单可见性的响应式函数
const isMenuItemVisible = computed(() => (item: string) => {
  // Home 和 Restart 始终可见(可根据需求调整)
  if (item === 'home' || item === 'restart') return true
  
  // 未登录时隐藏 Update 和 Delete
  if (!username.value) return false
  
  // Admin 用户隐藏 Update
  if (username.value === 'admin') {
    return item !== 'update'
  }
  
  // Staff 用户隐藏 Delete
  if (username.value === 'staff') {
    return item !== 'delete'
  }
  
  // 默认显示所有菜单
  return true
})
</script>

可见性规则说明

  • 未登录状态:仅显示 Home 和 Restart(若需仅显示 Home,移除 item === 'restart' 即可)
  • Admin登录:隐藏 Update,显示 Home、Delete、Restart
  • Staff登录:隐藏 Delete,显示 Home、Update、Restart

关键改进点

  1. 响应式同步:登录时更新 Pinia 的 user 变量,确保导航栏实时感知状态变化
  2. 逻辑复用:通过单一函数集中管理所有菜单的可见性判断,避免重复代码
  3. 鲁棒性提升:对用户名做 trim 处理,避免空格导致的判断错误
  4. 可维护性:权限规则集中管理,后续修改只需调整 isMenuItemVisible 函数

内容的提问来源于stack exchange,提问作者Divya Bharathi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 02:20:26