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

Vue-Electron如何自定义顶部菜单栏?将菜单元素移至标题栏

Electron + Vue 自定义标题栏实现方案

要把系统菜单栏迁移到自定义标题栏,分以下几个核心步骤实现:

1. 主进程配置:隐藏默认菜单栏与系统标题栏

在Electron主进程文件(通常是main.js)中,做以下配置:

  • 隐藏系统默认应用菜单栏
  • 创建无边框窗口,同时保留窗口的拖动、缩放能力
const { app, BrowserWindow, Menu } = require('electron')

function createWindow() {
  // 隐藏默认应用菜单栏
  Menu.setApplicationMenu(null)

  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    frame: false, // 去掉系统默认边框和标题栏
    webPreferences: {
      nodeIntegration: true, 
      contextIsolation: false,
      enableRemoteModule: true 
    }
  })

  mainWindow.loadURL('http://localhost:8080') // Vue开发环境地址,打包后替换为loadFile路径
}

app.whenReady().then(createWindow)

2. Vue渲染进程:自定义标题栏组件

在Vue项目中创建自定义标题栏组件(比如components/TitleBar.vue),包含菜单选项和窗口控制按钮,同时通过CSS实现拖动效果:

<template>
  <div class="title-bar">
    <!-- 自定义菜单区域 -->
    <div class="menu-group">
      <button class="menu-item" @click="handleFileMenu">文件</button>
      <button class="menu-item" @click="handleEditMenu">编辑</button>
      <button class="menu-item" @click="handleViewMenu">视图</button>
    </div>
    <!-- 窗口控制按钮 -->
    <div class="window-controls">
      <button class="control-btn" @click="minimizeWindow">-</button>
      <button class="control-btn" @click="toggleMaximizeWindow">□</button>
      <button class="control-btn close-btn" @click="closeWindow">×</button>
    </div>
  </div>
</template>

<script>
const { ipcRenderer } = require('electron')

export default {
  methods: {
    // 菜单逻辑示例:触发主进程对应操作
    handleFileMenu() {
      ipcRenderer.send('trigger-file-menu')
    },
    handleEditMenu() {
      ipcRenderer.send('trigger-edit-menu')
    },
    handleViewMenu() {
      ipcRenderer.send('trigger-view-menu')
    },
    // 窗口控制逻辑
    minimizeWindow() {
      ipcRenderer.send('window-minimize')
    },
    toggleMaximizeWindow() {
      ipcRenderer.send('window-toggle-maximize')
    },
    closeWindow() {
      ipcRenderer.send('window-close')
    }
  }
}
</script>

<style scoped>
.title-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 36px;
  background-color: #2c3e50;
  color: #fff;
  padding: 0 12px;
  -webkit-app-region: drag; /* 允许标题栏拖动窗口 */
}

.menu-item, .control-btn {
  background: transparent;
  border: none;
  color: #fff;
  padding: 8px 12px;
  cursor: pointer;
  -webkit-app-region: no-drag; /* 按钮禁止拖动,确保可点击 */
}

.menu-item:hover, .control-btn:hover {
  background-color: #34495e;
}

.close-btn:hover {
  background-color: #e74c3c;
}

.window-controls {
  display: flex;
  gap: 4px;
}
</style>

3. 主进程与渲染进程通信

在主进程中监听渲染进程发送的事件,处理菜单操作和窗口控制:

// 继续在main.js中添加
const { ipcMain, dialog } = require('electron')

// 菜单事件处理示例
ipcMain.on('trigger-file-menu', async () => {
  const result = await dialog.showOpenDialog({
    properties: ['openFile']
  })
  console.log('选中文件:', result.filePaths)
  // 这里添加业务逻辑
})

// 窗口控制事件监听
ipcMain.on('window-minimize', () => {
  const window = BrowserWindow.getFocusedWindow()
  window.minimize()
})

ipcMain.on('window-toggle-maximize', () => {
  const window = BrowserWindow.getFocusedWindow()
  window.isMaximized() ? window.unmaximize() : window.maximize()
})

ipcMain.on('window-close', () => {
  const window = BrowserWindow.getFocusedWindow()
  window.close()
})

4. 集成自定义标题栏到Vue页面

在Vue主页面(比如App.vue)中引入并使用自定义标题栏:

<template>
  <div id="app">
    <TitleBar />
    <!-- 页面核心内容 -->
    <router-view />
  </div>
</template>

<script>
import TitleBar from './components/TitleBar.vue'

export default {
  components: {
    TitleBar
  }
}
</script>

注意事项

  • 若使用Electron v12+版本,建议用**预加载脚本(preload.js)**替代直接开启nodeIntegration,避免安全风险
  • 自定义菜单的下拉展开逻辑可通过Vue弹窗组件实现(如Element UI的Dropdown)
  • 不同平台(Windows/macOS)的窗口控制按钮样式、位置有差异,可根据平台做适配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 06:05:17