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 管理;
  • 响应式:状态变动自动驱动菜单显示;
  • 架构清晰:结构清晰、职责单一、便于维护;
  • 设计模式合理:策略模式 + 观察者模式 + 函数式更新。

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

📚 延伸阅读


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

相关推荐
烛阴18 分钟前
带你用TS彻底搞懂ECS架构模式
前端·javascript·typescript
卓码软件测评1 小时前
【第三方网站运行环境测试:服务器配置(如Nginx/Apache)的WEB安全测试重点】
运维·服务器·前端·网络协议·nginx·web安全·apache
龙在天1 小时前
前端不求人系列 之 一条命令自动部署项目
前端
开开心心就好1 小时前
PDF转长图工具,一键多页转图片
java·服务器·前端·数据库·人工智能·pdf·推荐算法
国家不保护废物1 小时前
10万条数据插入页面:从性能优化到虚拟列表的终极方案
前端·面试·性能优化
文心快码BaiduComate1 小时前
七夕,画个动态星空送给Ta
前端·后端·程序员
web前端1231 小时前
# 多行文本溢出实现方法
前端·javascript
文心快码BaiduComate1 小时前
早期人类奴役AI实录:用Comate Zulu 10min做一款Chrome插件
前端·后端·程序员
人间观察员1 小时前
如何在 Vue 项目的 template 中使用 JSX
前端·javascript·vue.js
布列瑟农的星空2 小时前
大话设计模式——多应用实例下的IOC隔离
前端·后端·架构