在 electron 中有 3 種類型的 Menu
下面我們來介紹一下 , 3 種 Menu 各是甚麼 , 以及其存在的環境

當然我們可以也可以將其設定成我們想要的
// 加到 background.js 的 createWindow 函式中 
const applicationMenu = Menu.buildFromTemplate([
    {
        label: '編輯',
        submenu: [
            {role: 'undo', label: '返回'},
            {role: 'redo', label: '重做'},
            {type: 'separator'},
            {
                label: '常用功能',
                submenu: [
                    {role: 'cut'},
                    {role: 'copy'},
                    {role: 'paste'},
                    {role: 'delete'},
                ]
            },
            {type: 'separator'},
            {role: 'selectAll', label: '全選'}
        ]
    },
    {
        label: '關閉',
        click: () => app.quit(),
    },
]);
Menu.setApplicationMenu(applicationMenu);

由於 electron 的 applicationMenu 無法調整高度 . 背景色 ...等樣式 ,
所以大部分的 electron 程式不會使用 applicationMenu ,
而是會自己用 html + css 客製化一個標題列
( 如果想要客製化一個標題列 , 可參考 昨天的文章 )

vscode:將標題列與工具列放在同一列顯示


我們將 "動物聊天室" 追加彈跳選單
將 中的文字區塊加上 @contextmenu 使其對右鍵產生反應
- <div class="msg" :class="[chat.team]">
+ <div class="msg" :class="[chat.team]" @contextmenu="openMenu(chat)">
    <span class="break-words">
       {{chat.msg}}
    </span>
</div>
當然我們要設定 method - openMenu
methods: {
    openMenu(chat) {
    
        window.ipcRenderer.send('open-contextmenu', chat);
    },
    ...
}
ipcRenderer 送出 open-contextmenu , 因此 background.js 需要註冊 ipcMain.on('open-contextmenu' 來接受訊息
ipcMain.on('open-contextmenu', (event, chat) => {
    Menu.buildFromTemplate([
        {label: '複製', click: () => event.reply('chatroom:copy-msg', chat)},
        {label: '刪除', click: () => event.reply('chatroom:delete-msg', chat)},
        {label: '收回', click: () => event.reply('chatroom:take-back-msg', chat)},
    ])
        .popup(BrowserWindow.getFocusedWindow())
});
然而 , 複製 . 刪除 . 收回 這些動作必定需要更新畫面 ,
因此用 event.reply 請求畫面更新 ,
並在 created 時註冊對應的 ipcRenderer.on
created() {
    // 複製訊息
    window.ipcRenderer.on('chatroom:copy-msg', (event, chat) => {
        this.text = chat.msg;
        this.$refs['text-input'].focus();
    });
    //  刪除訊息
    window.ipcRenderer.on('chatroom:delete-msg', (event, chat) => {
        firestoreUtils.sender
            .deleteMessage(this.roomId, chat.uuid)
            .catch(e => console.error(e));
    });
    //  收回訊息
    window.ipcRenderer.on('chatroom:take-back-msg', (event, chat) => {
        firestoreUtils.sender
            .updateMessage(this.roomId, {...chat, takeBack: true})
            .catch(e => console.error(e));
    });
},
之前我們沒有設計 收回訊息 的樣式 , 因此需要追加設計一下
在 Chatroom.vue 的  中追加 v-if 判別此訊息要顯示收回 or 詳細內容
<div v-if="chat.takeBack"
     :key="chat.uuid"
     class="msg-wrap justify-center"
>
    <div class="take-back-msg">
        <span> {{chat.name}} 已收回訊息 </span>
    </div>
</div>
上方追加區塊多使用了 justify-center 和 take-back-msg ,
因此需要在  區塊中定義一下
.justify-center {
    justify-content: center;
}
.take-back-msg{
    padding: 3px 20px 3px 20px;
    border-radius: 30px;
    color: white;
    background-color: #8F8989;
}

  const switchCat = catNo => () => { 
      win.show();
      win.webContents.send('switch-cat', catNo);
  }
  tray = new Tray('/path/to/my/icon');
  const contextMenu = Menu.buildFromTemplate([
      {label: '貓咪 4', click: switchCat(4)},
      {label: '貓咪 5', click: switchCat(5)},
      {label: '貓咪 6', click: switchCat(6)},
      {label: '縮小', click: () => win.hide()},
      {label: '結束', click: () => app.quit()}
  ]);
  tray.setToolTip('This is my application.'); // 提示訊息
  tray.setContextMenu(contextMenu);   // 右鍵選單
不知道邦友有沒有覺得熟悉 ?
其實在 [ Day 5 ] - 桌面小圖示(四) - 系統通知區與縮小的貓咪 我們已經使用過了 ![]()
今年小弟第一次參加 `鐵人賽` , 如文章有誤 , 請各位前輩提出指正 , 感謝  <(_ _)>