electron自定义顶部

我的项目是采用的electron-vite搭建的,希望下面的内容可以给你带来帮助

自定义菜单栏Vue

javascript 复制代码
<template>
    <div class="title-bar">
      <div class="left-section">
        <img src="../assets/icon.png" alt="Icon" class="icon"/>
        <span class="title">云希网盘</span>
      </div>
      <div class="right-section">
        <button @click="changeSkin">
        //这里一定记得自己的路径配置
        <img src="../assets/icon-image/huanfu.png" alt="换肤" class="icon-button " style="width: 23px; height: 23px;" title="换肤"/>
      </button>
      <button @click="toggleTop">
        <img src="../assets/icon-image/no-top.png" alt="" v-if="isTop" class="icon-button " title="取消置顶">
        <img src="../assets/icon-image/top.png" alt="" v-else class="icon-button " title="置顶">
        
      </button>
      <button @click="minimizeWindow">
        <img src="../assets/icon-image/mini.png" alt="小化" class="icon-button" title="小化"/>
      </button>
      <button @click="maximizeWindow">
        <img src="../assets/icon-image/big.png" alt="放大" class="icon-button" title="全屏"/>
      </button>
      <button @click="closeWindow">
        <img src="../assets/icon-image/close.png" alt="关闭" class="icon-button" title="关闭"/>
      </button>
      </div>
    </div>
  </template>
  
  <script setup>
  import { ref, onMounted } from 'vue';
  const { ipcRenderer } = window.electron;
  
  const isTop = ref(false);
  
  const changeSkin = () => {
    // 换肤逻辑
  };
  
  const toggleTop = () => {
    ipcRenderer.send('toggle-top');
    isTop.value = !isTop.value;
  };
  
  const minimizeWindow = () => {
    ipcRenderer.send('minimize-window');
  };
  
  const maximizeWindow = () => {
    ipcRenderer.send('maximize-window');
  };
  
  const closeWindow = () => {
    ipcRenderer.send('close-window');
  };
  
  onMounted(() => {
    ipcRenderer.on('top-status-changed', (event, status) => {
      isTop.value = status;
    });
  });
  </script>
  
  <style scoped>
  .title-bar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 10px;
    height: 40px;
    background-color: white;
    color: black;
    -webkit-app-region: drag;
  }
  
  .left-section {
    display: flex;
    align-items: center;
  }
  
  .icon {
    width: 20px;
    height: 20px;
    margin-right: 10px;
  }
  
  .title {
    font-size: 13px;
  }
  
  .right-section {
    display: flex;
    gap: 10px;
  }
  
  button {
    background: none;
    border: none;
    color: black;
    cursor: pointer;
    -webkit-app-region: no-drag;
  }

  .icon-button {
  width: 20px;
  height: 20px;
  margin-right: 3px;
  &:hover{
    background-color: #c4c4c4;
  }
}
  </style>
  

electron主进程

javascript 复制代码
const mainWindow = new BrowserWindow({
    width: 1300,
    height: 780,
    minWidth:1250,
    minHeight:680,
    icon: join(__dirname,'../../build/icon.ico'),
    show: false,
    frame: false, // 这里一定要记得隐藏标题栏
    autoHideMenuBar: true,
    ...(process.platform === 'linux' ? { icon } : {}),
    webPreferences: {
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false
    },  
  })


ipcMain.on('toggle-top', (event) => {
    const win = BrowserWindow.getFocusedWindow();
    const isAlwaysOnTop = win.isAlwaysOnTop();
    win.setAlwaysOnTop(!isAlwaysOnTop);
    event.sender.send('top-status-changed', !isAlwaysOnTop);
  });
  
  ipcMain.on('minimize-window', (event) => {
    const win = BrowserWindow.getFocusedWindow();
    win.minimize();
  });
  
  ipcMain.on('maximize-window', (event) => {
    const win = BrowserWindow.getFocusedWindow();
    if (win.isMaximized()) {
      win.unmaximize();
    } else {
      win.maximize();
    }
  });
  
  ipcMain.on('close-window', (event) => {
    const win = BrowserWindow.getFocusedWindow();
    win.close();
  });

App.vue代码

javascript 复制代码
<template>
  <div class="main">
    <Navi></Navi>
    <el-config-provider :locale="locale" :message="config">
      <router-view></router-view>
    </el-config-provider>
  </div>
  </template>
  
  <script setup>
  import { reactive } from "vue";
  import Navi from "./components/Navi.vue";
  import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
  const locale = zhCn;
  const config = reactive({
    max: 1,
  });
  </script>
  
  <style lang="scss" scoped>
    .main{
      width: 100vw;
      height: 100vh;
      overflow: hidden;
    }
  </style>
  

最终运行效果

相关推荐
负责的蛋挞3 分钟前
异步HttpModule的实现方式
java·服务器·前端
丹宇码农3 小时前
把 HLS 字幕玩出花:zwPlayer 如何让 M3U8 视频支持全文搜索、翻译与码率自适应
前端·javascript·音视频·hls·视频播放器
2501_943782353 小时前
【共创季稿事节】猜数字游戏:二分法思维与交互式反馈
前端·游戏·microsoft·harmonyos·鸿蒙·鸿蒙系统
GV191rLvq3 小时前
基于Socket实现的最简单的Web服务器【ASP.NET原理分析】
服务器·前端·asp.net
吠品3 小时前
LangChain 里 tool_call_id 为空?一次 MCP 工具集成的排查记录
前端
微信开发api-视频号协议3 小时前
企业微信二次开发中的文件系统设计:媒体资源、临时文件与业务附件
前端·微信·企业微信·媒体·ipad·微信开放平台
柒和远方3 小时前
Phase 7.4 学习博客:为什么多 API 项目需要 Swagger / OpenAPI
前端·后端·架构
张龙6873 小时前
拼多多开放平台对接踩坑实录:从 CLIENT_ID 配置到 MD5 签名算法的完整填坑指南
前端
GuWenyue4 小时前
提示词彻底过时?一套上下文工程方案,3步让LLM落地生产,代码直接复用
前端·javascript·人工智能