Files
map-client-vue/web/MODAL_FIX_GUIDE.md
2025-10-14 14:18:20 +08:00

7.6 KiB
Raw Blame History

🔧 编辑按钮修复说明

问题描述

点击 MCP 服务器卡片上的"编辑"按钮后,没有弹出服务器详情编辑页面。

根本原因

Naive UI 的 n-modal 组件需要将内容包装在 n-card 中才能正确显示。之前的实现直接将 MCPServerDetail 组件放在 n-modal 内,导致样式和布局问题。

修复内容

修复 1: 正确包装 Modal 内容

文件: web/src/components/MCPSettings.vue

之前的代码 (错误):

<n-modal 
  v-model:show="showServerDetail" 
  :style="{ width: '90%', maxWidth: '1200px' }"
  preset="card"
>
  <MCPServerDetail ... />
</n-modal>

修复后的代码 (正确):

<n-modal v-model:show="showServerDetail">
  <n-card
    style="width: 90%; max-width: 1200px"
    title="服务器详情"
    :bordered="false"
    size="huge"
    role="dialog"
    aria-modal="true"
  >
    <MCPServerDetail ... />
  </n-card>
</n-modal>

关键变化:

  • 移除了 modal 上的 preset="card" 属性
  • 添加了 n-card 包裹组件
  • 将样式从 modal 移到 card 上
  • 添加了无障碍属性 (role, aria-modal)

修复 2: 增强调试日志

文件: web/src/components/MCPSettings.vue

openServerDetail 函数中添加了详细的步骤日志:

const openServerDetail = (server: any) => {
  console.log('🔍 [1] 打开服务器详情被调用')
  console.log('🔍 [2] 服务器数据:', server)
  console.log('🔍 [3] 当前 showServerDetail 值:', showServerDetail.value)
  
  try {
    editingServer.value = { ...server }
    console.log('🔍 [4] editingServer 设置完成:', editingServer.value)
    
    showServerDetail.value = true
    console.log('✅ [5] showServerDetail 设置为 true')
    console.log('✅ [6] 最终状态检查 - showServerDetail:', showServerDetail.value, 'editingServer:', editingServer.value)
  } catch (error) {
    console.error('❌ openServerDetail 出错:', error)
  }
}

测试步骤

1. 确保服务器运行

cd /Users/gavin/xhs/mcp_client/mcp-client-vue/web
npm run dev

服务器应该运行在: http://localhost:5173

2. 打开浏览器调试工具

  • Mac: Cmd + Option + I
  • Windows/Linux: F12
  • 切换到 Console 标签

3. 测试编辑功能

  1. 访问 http://localhost:5173
  2. 找到任意 MCP 服务器卡片
  3. 点击 "编辑" 按钮
  4. 预期结果:
    • 控制台显示 6 条日志([1] 到 [6]
    • 弹出服务器详情对话框
    • 对话框显示服务器的详细信息和 4 个标签页

4. 查看控制台输出

成功的输出示例:

🔍 [1] 打开服务器详情被调用
🔍 [2] 服务器数据: {id: "xxx", name: "test", url: "http://0.0.0.0:3100/mcp", ...}
🔍 [3] 当前 showServerDetail 值: false
🔍 [4] editingServer 设置完成: {id: "xxx", name: "test", ...}
✅ [5] showServerDetail 设置为 true
✅ [6] 最终状态检查 - showServerDetail: true editingServer: {...}

调试辅助工具

方法 1: 使用调试页面

访问: http://localhost:5173/modal-debug.html

这个页面提供了:

  • 📋 完整的调试步骤清单
  • 🔎 预期的控制台输出示例
  • 🐛 常见问题和解决方案
  • 🔧 快速修复脚本

方法 2: 浏览器控制台检查

如果 modal 仍然不显示,在控制台执行:

// 检查 modal 元素是否存在
const modal = document.querySelector('.n-modal')
console.log('Modal 元素:', modal)

// 检查 modal 的样式
if (modal) {
  const styles = window.getComputedStyle(modal)
  console.log('display:', styles.display)
  console.log('opacity:', styles.opacity)
  console.log('z-index:', styles.zIndex)
}

// 查找所有 modal 相关元素
console.log('所有 modal:', document.querySelectorAll('.n-modal'))
console.log('所有 modal container:', document.querySelectorAll('.n-modal-container'))

常见问题排查

Q1: 点击编辑按钮后,控制台完全没有日志

可能原因:

  • 页面缓存问题
  • JavaScript 错误阻止了代码执行
  • 按钮被其他元素遮挡

解决方案:

  1. 硬刷新页面 (Cmd+Shift+R / Ctrl+Shift+R)
  2. 清除浏览器缓存
  3. 检查 Console 中是否有红色错误信息
  4. 检查 Elements 标签中按钮的 DOM 结构

Q2: 有日志输出但 modal 不显示

可能原因:

  • Modal 渲染在错误的位置
  • CSS z-index 冲突
  • Naive UI 组件配置问题

解决方案:

  1. 在 Elements 标签中搜索 "n-modal"
  2. 检查 modal 元素的 CSS 样式
  3. 尝试在控制台手动显示 modal:
const modal = document.querySelector('.n-modal')
if (modal) {
  modal.style.display = 'flex'
  modal.style.opacity = '1'
  modal.style.zIndex = '9999'
}

Q3: Modal 显示但内容是空白的

可能原因:

  • editingServer 数据为空
  • MCPServerDetail 组件渲染错误
  • Props 传递问题

解决方案:

  1. 检查日志 [4] 和 [6],确认 editingServer 有数据
  2. 在 Console 中查看是否有 Vue 渲染警告
  3. 检查 MCPServerDetail 组件是否正确导入

技术细节

Naive UI Modal 最佳实践

根据 Naive UI 文档modal 的内容应该使用以下结构之一:

方式 1: 使用 n-card 包裹 (推荐,我们使用的方式)

<n-modal v-model:show="showModal">
  <n-card title="标题" :bordered="false" size="huge">
    <!-- 内容 -->
  </n-card>
</n-modal>

方式 2: 使用 preset="card"

<n-modal 
  v-model:show="showModal"
  preset="card"
  title="标题"
>
  <!-- 内容 -->
</n-modal>

方式 3: 自定义样式

<n-modal v-model:show="showModal">
  <div class="custom-modal-content">
    <!-- 内容 -->
  </div>
</n-modal>

我们选择方式 1 是因为:

  • 更灵活,可以完全控制 card 的样式
  • 与其他 modal (添加服务器、工具执行) 保持一致
  • 更好的语义化和无障碍支持

响应式状态管理

// Modal 显示状态
const showServerDetail = ref(false)

// 当前编辑的服务器数据
const editingServer = ref<any>(null)

// 打开 modal
const openServerDetail = (server: any) => {
  editingServer.value = { ...server } // 深拷贝避免直接修改
  showServerDetail.value = true
}

// 关闭 modal
const closeServerDetail = () => {
  showServerDetail.value = false
  editingServer.value = null
}

验证清单

测试前确保:

  • 开发服务器运行在 http://localhost:5173
  • 没有编译错误(检查终端输出)
  • 浏览器开发者工具已打开
  • Console 标签已选中
  • 页面已刷新(清除缓存)

测试步骤:

  • 可以看到 MCP 服务器卡片
  • 点击"编辑"按钮
  • 控制台显示完整日志([1] 到 [6]
  • Modal 对话框成功弹出
  • 可以看到服务器详情页面
  • 可以切换 4 个标签页 (通用/工具/提示词/资源)
  • 点击返回按钮可以关闭 modal

相关文件

  • /web/src/components/MCPSettings.vue - 主要修复文件
  • /web/src/components/MCPServerDetail.vue - 详情页面组件
  • /web/public/modal-debug.html - 调试辅助页面
  • /web/TYPESCRIPT_FIXES.md - TypeScript 类型修复文档

修复状态

Modal 包装结构修复完成 调试日志增强完成 调试辅助工具创建完成 开发服务器运行正常 无编译错误

🔄 待测试: 请在浏览器中验证编辑按钮是否正常工作

下一步

  1. 立即测试 - 打开 http://localhost:5173 并点击编辑按钮
  2. 查看日志 - 确认控制台有完整的日志输出
  3. 报告结果 - 告诉我是否成功,或提供控制台截图

如果仍有问题,请提供:

  • 浏览器控制台的完整输出(截图)
  • Elements 标签中搜索 "n-modal" 的结果
  • 是否有任何红色错误信息