vue?electron實現(xiàn)無邊框窗口示例詳解
一、前言
無邊框窗口是不帶外殼(包括窗口邊框、工具欄等),只含有網(wǎng)頁內(nèi)容的窗口。對于一個產(chǎn)品來講,桌面應用帶邊框的很少,因為丑(我們的UI覺得--與我無關(guān)-.-)。因此我們就來展開說下,在做無邊框窗口時候需要注意的事項以及我踩過的坑。
二、實現(xiàn)方案
1.創(chuàng)建無邊框窗口
要創(chuàng)建無邊框窗口,只需在 BrowserWindow 的 options
中將 frame
設(shè)置為 false
:
const { BrowserWindow } = require('electron') const win = new BrowserWindow({ width: 800, height: 600, // 設(shè)置為 `false` 時可以創(chuàng)建一個無邊框窗口。 默認值為 `true` frame: false, // 無標題時,在mac內(nèi),窗口將一直擁有位于左上的標準窗口控制器 (“traffic lights”) titleBarStyle: 'hidden', // mac設(shè)置控制按鈕在無邊框窗口中的位置。 trafficLightPosition: { x: 12, y: 18 }, // 在windows上,設(shè)置默認顯示窗口控制工具 titleBarOverlay: { color: "#fff", symbolColor: "black", } }) win.show()
在electron官網(wǎng)中有這么一段描述
titleBarStyle
String (可選) macOS Windows - 窗口標題欄樣式。 默認值為 default
. 可能的值有
hidden
- 在一個隱藏的標題欄和一個全尺寸大小的內(nèi)容窗口中取得結(jié)果。 在 macOS 內(nèi), 窗口將一直擁有位于左上的標準窗口控制器 (“traffic lights”)。- 在 Windows上,當與
titleBarOverlay: true
合并時,它將激活窗口控件疊加(詳情請參閱titleBarOverlay
),否則將不會顯示窗口控件
titleBarOverlay
Object | Boolean (可選) - 當使用無框窗口配置win.setWindowButtonVisibility(true)
在 macOS 或使用 titleBarStyle
可使標準窗口控制可見 ("traffic lights" on macOS) ,當前屬性開啟 Window Controls 覆蓋 JavaScript APIs 和 CSS Environment Variables 指定 true
將導致覆蓋默認系統(tǒng)顏色。 默認值為 false
.
這里說兩者配合使用,即titleBarStyle
為hidden
,并且titleBarOverlay
為true
或者對象時,則windows系統(tǒng)中,應用窗口也會默認顯示出window操作系統(tǒng)的窗口控件工具。
如圖所示
這樣我們就完成了,electron應用的無邊框窗口。
但是這樣的無邊框窗口僅能實現(xiàn)通用的樣式,應用頭部總是會被占用一條高度。并且不支持自定義標題欄。若你有自定義標題欄,或者嵌入式的windows窗口控件需求,請繼續(xù)往下看
2.創(chuàng)建windows窗口控件組件
因為我做的項目有windows窗口控件內(nèi)嵌頁面的需求,而且這樣也方便自定義標題欄,所以需要有這樣一個控件。例如下面這種情況
// WindowsTopControl.vue <template> <div class="windows-top-control" :style="{height:mainHeight + 'px'}" :class="{'main-bottom':border}"> <ul class="windows-top-control-win"> <li @click="controlWindow(1)"> <Icon type="最小化圖標" /> </li> <li @click="controlWindow(isFullScreen ? 3 : 2)"> <Icon :type="isFullScreen ? '最大化圖標' : '恢復正常圖標'" /> </li> <li class="close-icon" @click="controlWindow(0)"> <Icon type="關(guān)閉圖標" /> </li> </ul> </div> </template> <script> import { mapGetters, mapMutations } from 'vuex' const { ipcRenderer, remote } = require("electron") const WIN_CONTROL = { // 控件四種操作 0: 'close', 1: 'minimize', 2: 'maximize', 3: 'unmaximize' } export default { name: 'windowsTopControl', components: {}, props: { mainHeight: { type: String, default: '42' }, border: { type: Boolean, default: false } }, computed: { ...mapGetters(['isFullScreen']) }, mounted () { // 上來先設(shè)定當前窗口是否在最大化的狀態(tài) this.setIsFullScreen(remote.getCurrentWindow().isMaximized()) // 監(jiān)聽是否是最大化窗口 并 更改標識是否最大化 ipcRenderer.on('toggleMax', (e, isFullScreen) => { this.setIsFullScreen(isFullScreen) }) }, methods: { ...mapMutations(['setIsFullScreen']), controlWindow (val) { // 只有在2、3點擊時,修改是否全屏狀態(tài) if ([2, 3].includes(val)) { this.setIsFullScreen(val === 2) } remote.getCurrentWindow()[WIN_CONTROL[val]]() } }, } </script> <style lang="less" scoped> .windows-top-control { width: 100%; height: 42px; display: flex; justify-content: flex-end; .windows-top-control-win { width: 100%; height: 24px; display: flex; align-items: center; justify-content: flex-end; -webkit-app-region: drag; position: relative; li { width: 40px; height: 100%; text-align: center; line-height: 22px; cursor: pointer; -webkit-app-region: no-drag; position: absolute; pointer-events: auto; top: -2px; &:hover { background: #E0E4E5; } &:active { background: #CDCED0; } &:hover { color: #0183ff; } i { font-size: 14px; font-weight: 600; color: #1f2329; } } li:nth-child(1) { right: 78px; } li:nth-child(2) { right: 38px; } li:nth-child(3) { right: -2px; } } } .close-icon:hover { background: #FF6161 !important; i { color: #fff !important; } } .close-icon:active { background: #D64141 !important; i { color: #fff !important; } } .main-bottom { border-bottom: 1px solid #f6f6f6; } </style>
下面是vuex中的配置
// selectedState.js export default { state: { // 是否全屏(最大化) isFullScreen: window.sessionStorage.getItem('isFullScreen') || false, }, getters: { isFullScreen: state => state.isFullScreen }, mutations: { setIsFullScreen(state, val) { state.isFullScreen = val window.sessionStorage.setItem('isFullScreen', val) } } }
接下來 我們還需在主進程中,監(jiān)聽用戶的放大、縮小、最小化、關(guān)閉的操作。
// background.js // win是窗口實例 win.on('maximize', (event) => { event.sender.send('toggleMax', true) }) win.on('unmaximize', (event) => { event.sender.send('toggleMax', false) })
準備工作做完了,接下來我們就可以來引用使用組件啦,如下
// home.vue <template> <div> <WindowsTopControl mainHeight="24" /> </div> </template> <script> import WindowsTopControl from './WindowsTopControl.vue' export default { components: { WindowsTopControl } } </script>
以上,我們就完成了自定義的windows控件組就完成了,記得將窗口設(shè)置中的titleBarOverlay注釋掉!這樣我們就能自定義標題欄和內(nèi)嵌windows控件了。
三、后記
如果我們自定義控件這種方式實現(xiàn)的話,還需要考慮一點,那就是窗口的拖拽功能,一般情況下,我們拖拽的都是是窗口的頭部。這里我們可以給窗口提前注入一個js,去創(chuàng)建一個拖拽條,內(nèi)容如下
// WindowDrag.js // 在頂部插入一個的dom function initTopDrag () { const topDiv = document.createElement('div') // 創(chuàng)建節(jié)點 topDiv.style.position = 'fixed' // 一直在頂部 topDiv.style.top = '2px' topDiv.style.left = '2px' topDiv.style.height = '18px' // 頂部20px才可拖動 topDiv.style.width = 'calc(100% - 122px)' // 寬度100% topDiv.style.zIndex = '9999' // 懸浮于最外層 // topDiv.style.pointerEvents = 'none' // 用于點擊穿透 // @ts-ignore topDiv.style['-webkit-user-select'] = 'none' // 禁止選擇文字 // @ts-ignore topDiv.style['-webkit-app-region'] = 'drag' // 拖動 topDiv.id = 'drag-top-line' document.body.appendChild(topDiv) // 添加節(jié)點 } window.addEventListener('DOMContentLoaded', function onDOMContentLoaded () { initTopDrag() document.getElementById('drag-top-line').addEventListener('dblclick', e => { if (window.$isMac) { window.ipcRenderer.send('toggleMax') } }) })
在創(chuàng)建窗口時候引入
// background.js // 這里我將WindowDrag.js文件放在了public種 const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { preload: `${__static}/WindowDrag.js`, } })
如此我們就完成了拖拽條的設(shè)置。(如圖所示)
以上就是vue electron實現(xiàn)無邊框窗口示例詳解的詳細內(nèi)容,更多關(guān)于vue electron無邊框窗口的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Vuejs第十一篇組件之slot內(nèi)容分發(fā)實例詳解
這篇文章主要介紹了Vuejs第十一篇之slot內(nèi)容分發(fā)組件詳解的相關(guān)資料2016-09-09vue內(nèi)置組件keep-alive事件動態(tài)緩存實例
這篇文章主要介紹了vue內(nèi)置組件keep-alive事件動態(tài)緩存實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10vue2模擬vue-element-admin手寫角色權(quán)限的實現(xiàn)
本文主要介紹了vue2模擬vue-element-admin手寫角色權(quán)限的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-07-07