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>
  

最终运行效果

相关推荐
Ashley的成长之路42 分钟前
前端性能优化实战手册·第2篇:资源加载策略全解
前端·性能优化·资源加载·http/3·性能优化实战·资源加载优化
浅水壁虎1 小时前
vue基础(第二章 )
前端·javascript·vue.js
界面开发小八哥1 小时前
界面控件DevExtreme v26.1新版亮点——支持Angular 22
前端·javascript·angular.js·devexpress·ui开发·devextreme
Getflare1 小时前
前端 + UI 设计 + AI:这不是三个工种,是一个新三角能力模型(附自检清单)
前端·人工智能·ui
oil欧哟1 小时前
我做了一个 Vibe Coding 术语学习站:VibeHub
前端·ai·agent·独立开发·vibe coding
审小匠OpenCPAi2 小时前
银行流水核查怎么自动化?单边匹配、双向勾稽与图聚类异常检测的工程对比
java·前端·人工智能·python·审计
Revolution612 小时前
一个公共表格组件,是怎么一步步失控的
前端·前端工程化
腻害兔2 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:CRM 客户关系模块深度解析——从线索到回款,一套完整的 B2B 销售闭环是怎么搭的?
java·前端·javascript·vue.js·产品经理·ai编程
whyfail2 小时前
前端学 Spring Boot(2):一次点击,如何穿过整个后端?
前端·spring boot·后端