上贴传送门
electron 自定义标题栏
隐藏默认标题栏
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ frame: false })// frame设置为false
支持拖拽
默认情况下, 无边框窗口是不可拖拽的。 应用程序需要在 CSS 中指定 -webkit-app-region: drag
来告诉 Electron 哪些区域是可拖拽的(如操作系统的标准标题栏).
在可拖拽区域内部使用 -webkit-app-region: no-drag
则可以将其中部分区域排除。
可拖拽
body {
-webkit-app-region: drag;
}
不可拖拽
body {
-webkit-app-region: drag;
}
示例
目标
- 制作自定义标题栏,支持拖拽
- 制作自定义的最大\最小\关闭按钮
前提
基于上一帖的代码https://github.com/NightsLight-hub/vcped-test tag:1-ipc
引入ant-design-vue
本人非常喜欢ant-design-vue
框架, 本节主要以其作为基础组件库 在vcpeb-test 根目录使用如下命令安装ant-desing-vue
在main.js中引入antdyarn add ant-design-vue@next
import { createApp } from 'vue'; import App from './App.vue'; import router from './router'; import store from './store'; import Antd from 'ant-design-vue'; import 'ant-design-vue/dist/antd.css';
createApp(App).use(Antd).use(store).use(router).mount('#app');
## 修改`App.vue`,只保留一个`router-view`即可
```html
<template>
<router-view/>
</template>
<style lang="less">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
</style>
修改background.js的frame=false
const browserWindow = new BrowserWindow({
width: 800,
height: 600,
frame: false, // 关闭默认标题栏
webPreferences: {
// Use pluginOptions.nodeIntegration, leave this alone
// See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
preload: path.join(__dirname, 'preload.js')
}
});
修改Home.vue
<template>
<!-- 使用antd的header 布局,作为标题栏-->
<a-layout-header>
</a-layout-header>
<a-layout-content class="layout-content">
<div class="home">
<span>{{ msg }}</span>
</div>
</a-layout-content>
</template>
<script>
// @ is an alias to /src
export default {
name: 'Home',
data () {
return {
msg: ''
};
},
mounted () {
// eslint-disable-next-line no-debugger
debugger;
window.ipcRenderer.receive('mainMsg', (event, ...args) => {
console.log('get mainMsg');
this.msg = args[0];
});
}
};
</script>
<style scoped>
.ant-layout-header{
width: 100%;
height: 65px;
/* 标题栏设置个便于区分的颜色,可以拖拽用 */
background-color: #2c3e50;
/* 设置标题栏可以拖拽 */
-webkit-app-region: drag;
}
.layout-content{
height: calc(100vh - 100px);
width: 100%;
}
</style>
调试
yarn electron:serve
深色部分可以按住左键拖拽窗口
增加最大\最小\关闭按钮
增加三个按钮的组件 关闭按钮组件
<template>
<a-button id="closeButton" type="text" title="close" @click="closeWindow">
<template #icon><CloseOutlined /></template>
</a-button>
</template>
<script>
import { CloseOutlined } from '@ant-design/icons-vue';
export default {
name: 'closeButton',
components: {
CloseOutlined
},
methods: {
closeWindow () {
const ipcRenderer = window.ipcRenderer;
ipcRenderer.send('control', 'close');
}
}
};
</script>
<style>
#closeButton {
position: absolute;
width: 30px;
height: 30px;
top: 5px;
right: 20px;
margin: auto 0;
-webkit-app-region: no-drag;
}
</style>
最大化窗口按钮
<template>
<a-button id="maxButton" type="text" @click="maxWindow">
<template #icon><FullscreenOutlined /></template>
</a-button>
</template>
<script>
import { FullscreenOutlined } from '@ant-design/icons-vue';
export default {
name: 'maxButton',
components: {
FullscreenOutlined
},
methods: {
maxWindow () {
const ipcRenderer = window.ipcRenderer;
ipcRenderer.send('control', 'max');
}
}
};
</script>
<style>
#maxButton {
position: absolute;
width: 30px;
height: 30px;
top: 5px;
right: 60px;
margin: auto 0;
-webkit-app-region: no-drag;
}
</style>
最小化按钮
<template>
<a-button id="minButton" type="text" @click="minWindow">
<template #icon>
<FullscreenExitOutlined />
</template>
</a-button>
</template>
<script>
import { FullscreenExitOutlined } from '@ant-design/icons-vue';
export default {
name: 'MinButton',
components: {
FullscreenExitOutlined
},
methods: {
minWindow () {
const ipcRenderer = window.ipcRenderer;
ipcRenderer.send('control', 'min');
}
}
};
</script>
<style>
#minButton {
position: absolute;
width: 30px;
height: 30px;
top: 5px;
right: 100px;
margin: auto 0;
-webkit-app-region: no-drag;
}
</style>
三个按钮的点击事件利用ipcRender
,通过control
通道发送响应控制消息给主进程
比如最小化按钮
minWindow () {
const ipcRenderer = window.ipcRenderer;
ipcRenderer.send('control', 'min');
}
主进程增加对control
通道的响应
ipcMain.on('control', (event, ...args) => {
if (args[0] === 'min') {
browserWindow.minimize();
} else if (args[0] === 'max') {
if (browserWindow.isMaximized()) {
browserWindow.unmaximize();
} else {
browserWindow.maximize();
}
} else if (args[0] === 'close') {
console.log('close event');
browserWindow.close();
}
});
Home.vue
把三个按钮放到标题栏
<a-layout-header>
<close-button></close-button>
<max-button></max-button>
<min-button></min-button>
</a-layout-header>
适当调整了 标题栏背景色
.ant-layout-header{
width: 100%;
height: 65px;
/* 标题栏设置个便于区分的颜色,可以拖拽用 */
background-color: #18bae5;
/* 设置标题栏可以拖拽 */
-webkit-app-region: drag;
}
调试
获取本章代码
https://github.com/NightsLight-hub/vcped-test
tag: 2-customTitleBar