我的项目是采用的electron-vite搭建的,希望下面的内容可以给你带来帮助
自定义菜单栏Vue
<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主进程
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代码
<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>