Vue 实战:构建灵活可维护的菜单系统

在中后台系统中,菜单模块往往涉及复杂的权限控制、流程状态驱动、模块适配等逻辑。本文结合真实开发实践,从配置结构设计 到状态响应式控制,构建出一套可扩展、高内聚的菜单系统。

📌 业务场景简介

假设我们有一个 Vue 项目中,存在多个模块(例如"管理端"、"用户端"),它们需要展示不同的功能菜单。同时,一些菜单项的显示还取决于全局状态(如某个流程是否已完成)或角色权限等。

❌ 常见做法(反面教材):

js 复制代码
if (isAdmin) {
  menuList.push({ title: '审批入口', show: true });
}

这种写法的问题:

  • 👎 菜单定义散落在各处;
  • 👎 难以统一维护顺序;
  • 👎 与模块/状态强耦合,不利扩展。

✅ 第一阶段:菜单配置结构设计(Configuration-Driven)

我们首先将所有菜单项集中到一个配置列表中,并引入 variants 字段表示适用模块(或角色):

js 复制代码
// constants/menu.js

const allMenus = [
  { title: '功能 A', href: 'featureA', icon: 'setting', show: true, variants: ['admin'] },
  { title: '功能 B', href: 'featureB', icon: 'user', show: true, variants: ['user'] },
  { title: '公共功能', href: 'common', icon: 'appstore', show: true },
];

export function getMenuByRole(role = 'user') {
  return allMenus.filter(item => !item.variants || item.variants.includes(role));
}

在组件中使用:

js 复制代码
const menuList = getMenuByRole('admin');

🎯 设计思想 1:配置驱动开发(Configuration over Code)

通过结构化数据控制 UI 行为,避免硬编码逻辑。

你不需要再写 if (role === 'admin') 来添加菜单,只需写一条配置。

✅ 第二阶段:菜单项状态控制(State-Driven)

除了模块角色,菜单展示还依赖全局状态,例如:

  • "流程完成"后才展示"查看结果";
  • "已提交"后才展示"审批记录"。

我们使用 Vuex 存储状态:

js 复制代码
// store/index.js
state: {
  workflowStatus: 'inReview', // 'done', 'pending'...
}

在组件中响应式控制:

js 复制代码
computed: {
  workflowStatus() {
    return this.$store.state.workflowStatus;
  }
},
watch: {
  workflowStatus: {
    handler(status) {
      this.menuList = this.menuList.map(item => {
        if (item.href === 'result') {
          return { ...item, show: status === 'done' };
        }
        return item;
      });
    },
    immediate: true,
  }
}

🎯 设计思想 2:响应式编程(Reactive Programming)

你不是在命令式控制菜单项,而是让菜单展示成为 状态 => UI 的映射。

✅ 第三阶段:结构更新的正确方式

我们使用 .map() 返回新的菜单项列表,而不是直接修改原数组项:

js 复制代码
this.menuList = this.menuList.map(item => {
  if (item.href === 'result') {
    return { ...item, show: true };
  }
  return item;
});

🎯 设计思想 3:不可变数据(Immutable Data)

  • 保证响应式系统正确追踪变化;
  • 避免副作用,利于调试和测试;
  • 与函数式思想一致:函数输入输出明确,不修改外部状态。

🔍 深入分析:背后的设计模式

应用点 使用的设计模式或原则 解释
variants 模块控制 ✅ 策略模式(Strategy) 菜单展示策略由模块名决定
watch workflowStatus ✅ 观察者模式(Observer) 状态变化触发 UI 更新
filter(item => ...) ✅ 开放封闭原则(OCP) 增加菜单项无需修改逻辑
配置统一集中管理 ✅ 单一职责原则(SRP) 菜单结构与展示逻辑分离
.map() 返回新数组 ✅ 函数式编程思想 保持纯函数和数据不可变性

🧠 系统设计的提升点

  • 结构清晰:菜单项一目了然,结构统一。
  • 高扩展性:新增模块、角色、状态只需调整配置。
  • 低耦合:菜单配置与业务逻辑解耦,利于重构。
  • 响应驱动:状态变化自动驱动 UI,无需手动触发。

📦 可推广的应用场景

这套方案不仅适用于菜单:

  • ✅ 表单项展示/禁用(根据流程或权限);
  • ✅ 按钮权限(根据角色控制按钮是否展示);
  • ✅ 工作流面板(根据阶段展示不同面板);
  • ✅ 操作入口(如模块快捷操作区);

只要你遇到"多个 UI 元素是否展示依赖某些条件",都可以用这套方式统一解决。

✅ 总结

本次实战我们构建了一个:

  • ✅ 模块化:不同模块菜单通过 variants 管理;
  • ✅ 响应式:状态变动自动驱动菜单显示;
  • ✅ 架构清晰:结构清晰、职责单一、便于维护;
  • ✅ 设计模式合理:策略模式 + 观察者模式 + 函数式更新。

这不只是一个"菜单优化技巧",而是一套可以迁移到整个系统的可配置 + 状态驱动 + 响应式更新的架构思想。

📚 延伸阅读


📌 希望这篇文章能帮助你在项目中构建更清晰、更可维护的前端架构。如果你觉得有帮助,欢迎点赞 + 收藏 + 评论交流!

相关推荐
console.log('npc')24 分钟前
[特殊字符] AI Agent 工作台前端实战教程 · 新手入门指南
前端·人工智能
gCode Teacher 格码致知27 分钟前
前端教学2:ul标签的应用场合与经典案例
前端
const_qiu1 小时前
第 2.5 章 2.5.6:前端登录、Token 无感续签与路由守卫
java·前端·人工智能·状态模式
用户83134859306981 小时前
Vue3 事件:常用用法与开发高频坑点
前端·javascript·vue.js
weixin_446260851 小时前
ReAct‑Evolve:基于轨迹反馈的ReAct智能体自主提示演化系统
前端·react.js·前端框架
其实防守也摸鱼1 小时前
存储管理:页面置换算法学习任务(测验题要求给出置换页面顺序,缺页次数,缺页率)
android·前端·数据库·学习·oracle·自动化
怒放的生命19911 小时前
前端项目 Docker 打包实操指南
前端·docker·容器
tedcloud1231 小时前
Docker Compose 部署 Immich:手机照片自动备份与常见故障排查
运维·前端·docker·容器·智能手机·开源·流程图
时间的情敌1 小时前
《WebGIS 前端的成长路线,三维可视化工程师需要掌握什么》
前端·状态模式
漫步人生走在路上1 小时前
用小语种SEO突破外贸B2B天花板:法语、德语市场的实测数据
开发语言·前端·javascript·人工智能·搜索引擎·ecmascript