Electron Vue之间的通讯 自定义标题栏实现最小化全屏关闭功能

方便以后定制化使用,学习记录一下。
话不多说,先看看效果吧。

效果

img

版本

  • electron ^13.0.0

知识点

Vue 相互通讯 Electron 标题栏主要逻辑代码

新建public\preload.js文件,用于前端全局发送和监听消息。

const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('electronAPI', {
    minimize: () => ipcRenderer.send('minimize'),
    windowization: () => ipcRenderer.send('windowization'),
    maximize: () => ipcRenderer.send('maximize'),
    quit: () => ipcRenderer.send('quit'),
    onIsMaximizable: (callback) => ipcRenderer.on('is-maximizable', callback)
})

修改src\background.js文件,用于Electron接受发送消息。

async function createWindow() {
  // Create the browser window.
  win = 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: process.env.WEBPACK_DEV_SERVER_URL ? path.join(__dirname, 'bundled', 'preload.js') : path.join(__dirname, 'preload.js')
    }
  })


  win.on('maximize', (event) => {
    console.log("窗口最大化")
    win.webContents.send('is-maximizable', true)
  })
  win.on('resize', (event) => {
    console.log("窗口还原");
    win.webContents.send('is-maximizable', win.isMaximized())
  })
}

ipcMain.on('minimize', (event) => {
  win.minimize()
})
ipcMain.on('quit', (event) => {
  app.quit()
})
ipcMain.on('maximize', (event) => {
  win.maximize()
})
ipcMain.on('windowization', (event) => {
  win.restore();
})

关于打包构建调试,preload.js加载路径可能不同,所以需要根据不同环境进行判断。

preload: process.env.WEBPACK_DEV_SERVER_URL ? path.join(__dirname, 'bundled', 'preload.js') : path.join(__dirname, 'preload.js')

新建src\components\TitleBar.vue组件,标题栏样式和调用preload.js中的方法。

<template>
  <div class="title-bar">
    <div class="title-bar__left">
      <img class="title-bar__logo" src="../assets/logo.png" />
      <div class="title-bar__title">Vue 桌面程序</div>
    </div>
    <div class="title-bar__right" :style="{ '-webkit-app-region': 'no-drag' }">
      <div class="title-bar__icon" @click="minimize">
        <i class="iconfont icon-window-min_line"></i>
      </div>
      <div class="title-bar__icon" @click="windowization" v-show="isMaximizable">
        <i class="iconfont icon-window-window_line"></i>
      </div>
      <div class="title-bar__icon" @click="maximize" v-show="!isMaximizable">
        <i class="iconfont icon-window-max_line"></i>
      </div>
      <div class="title-bar__icon" @click="quit">
        <i class="iconfont icon-delete_line"></i>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  created() {
    this.onIsMaximizable();
  },
  data() {
    return {
      isMaximizable: false,
    };
  },
  methods: {
    minimize() {
      console.log("最小化");
      window.electronAPI.minimize();
    },
    windowization() {
      console.log("窗口化");
      window.electronAPI.windowization();
    },
    maximize() {
      console.log("最大化");
      window.electronAPI.maximize();
    },
    quit() {
      console.log("退出");
      window.electronAPI.quit();
    },
    onIsMaximizable() {
      window.electronAPI.onIsMaximizable((event, isMaximizable) => {
        console.log("监听窗口的变化", isMaximizable);
        this.isMaximizable = isMaximizable;
      });
    },
  },
};
</script>

<style lang="scss" scoped>
@import url("../assets/css/iconfont.css");

.title-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: #ddd;
  height: 30px;
  -webkit-app-region: drag;
  .title-bar__logo {
    width: 25px;
    height: 25px;
    margin-left: 10px;
  }
  .title-bar__title {
    margin-left: 6px;
  }
  .title-bar__right {
    margin-right: 10px;
  }
  .title-bar__icon {
    margin-left: 10px;
  }
  .title-bar__left,
  .title-bar__right {
    display: flex;
    align-items: center;
  }
  .title-bar__icon {
    display: flex;
    :active {
      background-color: #999;
    }
  }
}
</style>

src\App.vue页面中引用。

需要调整好样式不然滚动条就…🏊‍

<template>
  <div id="app">
    <title-bar></title-bar>
    <div class="app-body">
      <div id="nav">
        <router-link to="/">Home</router-link> |
        <router-link to="/about">About</router-link>
      </div>
      <router-view />
    </div>
  </div>
</template>
<script>
import TitleBar from "./components/TitleBar.vue";
export default {
  components: { TitleBar },
};
</script>
<style lang="scss">
body {
  margin: 0;
  overflow: hidden;
}
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  overflow: hidden;
  height: 100vh;
}
.app-body {
  overflow: auto;
  height: 100%;
}
#nav {
  padding: 30px;
  a {
    font-weight: bold;
    color: #2c3e50;

    &.router-link-exact-active {
      color: #42b983;
    }
  }
}
</style>

注意:修改完后记得先执行yarn run electron:build,直接执行yarn run electron:serve,对应的preload.js可能会是旧的文件。

隐藏菜单栏

修改src\background.js文件

import { Menu } from "electron";

// 禁用菜单栏
Menu.setApplicationMenu(null);
隐藏标题栏

修改src\background.js文件

import { BrowserWindow } from "electron";

async function createWindow() {
  // Create the browser window.
  win = new BrowserWindow({
    width: 800,
    height: 600,
    // 框架隐藏
    frame: false,
    webPreferences: {
      nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
      contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
    }
  })

  // 略
}

设置拖动窗体

修改src\App.vue文件

-webkit-app-region: drag 用于设定该部分为可拖动区域
-webkit-app-region: no-drag 用于设定该部分为不可拖动区域

<div id="app" style="-webkit-app-region: drag"></div>

相关文档

https://www.electronjs.org/zh/docs/latest/tutorial/context-isolation

源码

可能会有点乱,大多重点代码都在文章里了。

https://github.com/linyisonger/Vue.Examples

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林一怂儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值