Skip to content

Electron 自定义头部

第一步关闭系统自带的

  • 找到 config.prod.js

  • 找到 config.local.js

  • 找到 config.default.js

ts
// 把里面的 openAppMenu = true 改为 false
config.openAppMenu = false;

第二步 新建 自定义头部

  • 自定义头部涉及三个功能
  1. 关闭窗口
  2. 最小化窗口
  3. 最大化窗口

自定义头部

  • 写样式
vue
<template>
  <div class="headercontent">
    <!--移动-->
    <div class="header-container">
      <div class="col-logo"></div>

      <div class="col-channel">
        <div class="menu" @click="gotourl('home')">我的仪器</div>

        <div class="menu">方案中心</div>

        <div class="menu">仪器大全</div>

        <div class="menu">严选二手</div>

        <div class="menu">客户中心</div>
      </div>

      <div class="col-menu">
        <div class="row n1">
          <div class="btn" @click="menumin">
            <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
              <path
                d="M863.7 552.5H160.3c-10.6 0-19.2-8.6-19.2-19.2v-41.7c0-10.6 8.6-19.2 19.2-19.2h703.3c10.6 0 19.2 8.6 19.2 19.2v41.7c0 10.6-8.5 19.2-19.1 19.2z"
                fill="CurrentColor"
              ></path>
            </svg>
          </div>
          <div class="btn" @click="menumax" v-if="type == 'custom'">
            <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
              <path
                d="M711.99408722 829.71945954H312.00591278c-64.73350525 0-117.33913422-52.68287659-117.33913421-117.33913422V312.39215088c0-64.73350525 52.68287659-117.33913422 117.33913422-117.33913422h399.98817442c64.73350525 0 117.33913422 52.68287659 117.33913422 117.33913422v399.98817444c0 64.73350525-52.60562897 117.33913422-117.33913422 117.33913422zM312.00591278 256.85111236c-30.667305 0-55.54103852 24.95098115-55.54103851 55.54103852v399.98817444c0 30.667305 24.95098115 55.54103852 55.54103852 55.54103851h399.98817442c30.667305 0 55.54103852-24.95098115 55.54103852-55.54103851V312.39215088c0-30.667305-24.95098115-55.54103852-55.54103851-55.54103852H312.00591278z"
                fill="CurrentColor"
              ></path>
            </svg>
          </div>

          <div class="btn" @click="menumax" v-if="type == 'max'">
            <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
              <path
                d="M597.333333 426.666667v341.333333H256v-341.333333h341.333333m0-85.333334H256a85.333333 85.333333 0 0 0-85.333333 85.333334v341.333333a85.333333 85.333333 0 0 0 85.333333 85.333333h341.333333a85.333333 85.333333 0 0 0 85.333334-85.333333v-341.333333a85.333333 85.333333 0 0 0-85.333334-85.333334z"
                fill="CurrentColor"
              ></path>
              <path
                d="M768 170.666667h-341.333333a85.333333 85.333333 0 0 0-85.333334 85.333333v128h85.333334V256h341.333333v341.333333h-128v85.333334h128a85.333333 85.333333 0 0 0 85.333333-85.333334V256a85.333333 85.333333 0 0 0-85.333333-85.333333z"
                fill="CurrentColor"
              ></path>
            </svg>
          </div>

          <div class="btn" @click="menuclose">
            <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
              <path
                d="M567.168 512l189.184 188.352a40.064 40.064 0 0 1 0.768 55.68 37.76 37.76 0 0 1-54.4 0.832L512 566.912l-190.72 189.952a37.76 37.76 0 0 1-54.4-0.768 40.064 40.064 0 0 1 0.768-55.68L456.832 512 267.648 323.648a40.064 40.064 0 0 1-0.768-55.68 37.76 37.76 0 0 1 54.4-0.832L512 457.088l190.72-189.952a37.76 37.76 0 0 1 54.4 0.768 40.064 40.064 0 0 1-0.768 55.68L567.168 512z"
                fill="CurrentColor"
              ></path>
            </svg>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

写逻辑

  • 包含最大化,最小化,关闭
vue
<script>
import { ipc } from "@/utils/ipcRenderer";

export default {
  data() {
    return {
      type: "custom",
    };
  },
  mounted() {
    this.getrouter();
    // 监听更新
    ipc.on("controller.menu.onlistener", (event, result) => {
      console.log(result);
      this.percentage = parseInt(result.percent);
    });
    // 监听
    let _this = this;
    window.addEventListener("resize", function () {
      if (_this.isMaximized()) {
        _this.type = "max";
      } else {
        _this.type = "custom";
      }
    });
  },
  methods: {
    // 判断页面是否最大化
    isMaximized() {
      return (
        window.outerWidth === window.screen.availWidth &&
        window.outerHeight === window.screen.availHeight
      );
    },
    // 发送走最大化
    menumax() {
      ipc.invoke("controller.menu.menucontroller", "max").then((res) => {
        if (res == "max") {
          // 通过类型判断,如果最大化就显示最大化图标
          this.type = "max";
        } else if (res == "custom") {
          // 通过类型判断,如果不是最大化就显示自定义图标
          this.type = "custom";
        }
      });
    },
    // 发送最小化
    menumin() {
      ipc.send("controller.menu.menucontroller", "min");
    },
    // 发送关闭
    menuclose() {
      ipc.send("controller.menu.menucontroller", "close");
    },
  },
};
</script>

<template>
  <div class="headercontent">
    <!--移动-->
    <div class="header-container">
      <div class="col-logo"></div>

      <div class="col-channel">
        <div class="menu">我的仪器</div>

        <div class="menu">方案中心</div>

        <div class="menu">仪器大全</div>

        <div class="menu">严选二手</div>

        <div class="menu">客户中心</div>
      </div>

      <div class="col-menu">
        <div class="row n1">
          <div class="btn" @click="menumin">
            <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
              <path
                d="M863.7 552.5H160.3c-10.6 0-19.2-8.6-19.2-19.2v-41.7c0-10.6 8.6-19.2 19.2-19.2h703.3c10.6 0 19.2 8.6 19.2 19.2v41.7c0 10.6-8.5 19.2-19.1 19.2z"
                fill="CurrentColor"
              ></path>
            </svg>
          </div>
          <div class="btn" @click="menumax" v-if="type == 'custom'">
            <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
              <path
                d="M711.99408722 829.71945954H312.00591278c-64.73350525 0-117.33913422-52.68287659-117.33913421-117.33913422V312.39215088c0-64.73350525 52.68287659-117.33913422 117.33913422-117.33913422h399.98817442c64.73350525 0 117.33913422 52.68287659 117.33913422 117.33913422v399.98817444c0 64.73350525-52.60562897 117.33913422-117.33913422 117.33913422zM312.00591278 256.85111236c-30.667305 0-55.54103852 24.95098115-55.54103851 55.54103852v399.98817444c0 30.667305 24.95098115 55.54103852 55.54103852 55.54103851h399.98817442c30.667305 0 55.54103852-24.95098115 55.54103852-55.54103851V312.39215088c0-30.667305-24.95098115-55.54103852-55.54103851-55.54103852H312.00591278z"
                fill="CurrentColor"
              ></path>
            </svg>
          </div>

          <div class="btn" @click="menumax" v-if="type == 'max'">
            <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
              <path
                d="M597.333333 426.666667v341.333333H256v-341.333333h341.333333m0-85.333334H256a85.333333 85.333333 0 0 0-85.333333 85.333334v341.333333a85.333333 85.333333 0 0 0 85.333333 85.333333h341.333333a85.333333 85.333333 0 0 0 85.333334-85.333333v-341.333333a85.333333 85.333333 0 0 0-85.333334-85.333334z"
                fill="CurrentColor"
              ></path>
              <path
                d="M768 170.666667h-341.333333a85.333333 85.333333 0 0 0-85.333334 85.333333v128h85.333334V256h341.333333v341.333333h-128v85.333334h128a85.333333 85.333333 0 0 0 85.333333-85.333334V256a85.333333 85.333333 0 0 0-85.333333-85.333333z"
                fill="CurrentColor"
              ></path>
            </svg>
          </div>

          <div class="btn" @click="menuclose">
            <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
              <path
                d="M567.168 512l189.184 188.352a40.064 40.064 0 0 1 0.768 55.68 37.76 37.76 0 0 1-54.4 0.832L512 566.912l-190.72 189.952a37.76 37.76 0 0 1-54.4-0.768 40.064 40.064 0 0 1 0.768-55.68L456.832 512 267.648 323.648a40.064 40.064 0 0 1-0.768-55.68 37.76 37.76 0 0 1 54.4-0.832L512 457.088l190.72-189.952a37.76 37.76 0 0 1 54.4 0.768 40.064 40.064 0 0 1-0.768 55.68L567.168 512z"
                fill="CurrentColor"
              ></path>
            </svg>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.headercontent {
  .header-container {
    display: flex;
    align-items: center;
    height: 120px;
    width: 100%; /* 占满父容器的宽度 */
    background-color: #fff;
    border-bottom: 1px solid #ccc;
    // 拖拽关键因素
    -webkit-app-region: drag;
    // 左边占位
    .col-logo {
      flex: 0 0 300px;
    }
    // 中间占位
    .col-channel {
      display: flex;
      margin: 0 auto;
      svg {
        width: 25px;
      }
      .menu {
        display: flex;
        align-items: center;
        font-size: 16px;
        width: 90px;
        justify-content: center;
        border: 1px solid #ccc;
        padding-left: 15px;
        padding-right: 15px;
        line-height: 36px;
        border-radius: 8px;
        cursor: pointer;
        margin-right: 15px;
        // 点击中间的任意位置不允许拖拽
        -webkit-app-region: no-drag;
        &:hover {
          background-color: #eee;
        }
      }
    }
    // 右边按钮
    .col-menu {
      display: flex;
      flex-direction: column;
      margin: 0 15px 0 0;
      svg {
        width: 20px;
      }
      .row {
        display: flex;
        align-items: center;
        justify-content: right;
        //border:1px solid red;
        &.n1 {
          height: 30px;
        }
        &.n2 {
          height: 60px;
        }

        .btn {
          //border:1px solid red;
          display: flex;
          align-items: center;
          padding: 4px;
          margin: 0 10px 0 0;
          border-radius: 5px;
          cursor: pointer;
          -webkit-app-region: no-drag;
          &:hover {
            background-color: #eee;
          }
        }
      }
    }
  }
}
</style>

控制器

  • 控制器必须要传递 window 对象,不然无法控制窗口
ts
"use strict";
const { Controller } = require("ee-core");
const Services = require("ee-core/services");

class MenuController extends Controller {
  constructor(ctx) {
    super(ctx);
  }
  // 增加头部控制
  async menucontroller(content) {
    const { app } = this;
    const win = app.electron.mainWindow;

    switch (content) {
      case "max":
        const result = await Services.get("menuService").max(win);
        return result;
        break;
      case "min":
        await Services.get("menuService").min(win);
        break;
      case "close":
        const result2 = await Services.get("menuService").close();
        if (result2 === "close") {
          console.log("关闭");
          // 我这里直接关闭进程了 完全退出
          process.exit(0);
        }
        break;
      default:
        console.log("没找到");
        break;
    }
  }
}

MenuController.toString = () => "[class MenuController]";
module.exports = MenuController;

Services

ts
"use strict";
const autoUpdater = require("../updateutils/autoUpdater");
const { Service } = require("ee-core");

class MenuControllerService extends Service {
  constructor(ctx) {
    super(ctx);
  }
  async max(win) {
    if (win.isMaximized()) {
      win.restore();
      return "custom";
    } else {
      win.maximize();
      return "max";
    }
  }

  async min(win) {
    console.log(win);
    win.minimize();
    return "min";
  }

  async close() {
    return "close";
  }
}

MenuControllerService.toString = () => "[class MenuControllerService]";
module.exports = MenuControllerService;