自定义菜单栏实现点击添加按钮打开渲染进程的Dialog.vue模态框

实现思路:渲染进程页面初始化后就通知主进程,然后把event事件保存在该js文件外,当点击添加时因为是在其他位置,所以才要这样使用。然后点击添加后由主进程主动向渲染进程传递参数通知要做的操作。

代码如下:

// 第一步

// 进入主页面后给主进程通信 Home.vue
<script setup lang="ts" name="Home">
    import {provide, ref, onMounted} from 'vue'

    onMounted(async () => {
      window.getSource.openDialog()
    })

</script>



// preload.js
const {ipcRenderer, contextBridge} = require('electron')

const openDialog = () => ipcRenderer.send('on-opendialog-event')

contextBridge.exposeInMainWorld('getSource', {
    openDialog
})



// 主进程 main.js
const { app, Menu, ipcMain } = require('electron')

// 监听 on-opendialog-event 事件
let event = null
ipcMain.on('on-opendialog-event', (e, message) => {
    event = e;
})

// 第二步

// 主进程内自定义菜单点击 添加 后触发事件
const { app, Menu, ipcMain } = require('electron')

const isMac = process.platform === 'darwin'

// 监听 on-opendialog-event 事件
let event = null
ipcMain.on('on-opendialog-event', (e, message) => {
    event = e;
})


const template = [
  // { role: 'appMenu' }
  ...(isMac
    ? [{
        label: app.name,
        submenu: [
          { role: 'about' },
          { type: 'separator' },
          { role: 'services' },
          { type: 'separator' },
          { role: 'hide' },
          { role: 'hideOthers' },
          { role: 'unhide' },
          { type: 'separator' },
          { role: 'quit' }
        ]
      }]
    : []),
  // { role: 'fileMenu' }
  {
    label: 'File',
    submenu: [
      isMac ? { role: 'close' } : { role: 'quit' }
    ]
  },
  // { role: 'editMenu' }
  {
    label: 'Edit',
    submenu: [
      { role: 'undo' },
      { role: 'redo' },
      { type: 'separator' },
      { role: 'cut' },
      { role: 'copy' },
      { role: 'paste' },
      ...(isMac
        ? [
            { role: 'pasteAndMatchStyle' },
            { role: 'delete' },
            { role: 'selectAll' },
            { type: 'separator' },
            {
              label: 'Speech',
              submenu: [
                { role: 'startSpeaking' },
                { role: 'stopSpeaking' }
              ]
            }
          ]
        : [
            { role: 'delete' },
            { type: 'separator' },
            { role: 'selectAll' }
          ])
    ]
  },
  // { role: 'viewMenu' }
  {
    label: 'View',
    submenu: [
      { role: 'reload' },
      { role: 'forceReload' },
      { role: 'toggleDevTools' },
      { type: 'separator' },
      { role: 'resetZoom' },
      { role: 'zoomIn' },
      { role: 'zoomOut' },
      { type: 'separator' },
      { role: 'togglefullscreen' }
    ]
  },
  // { role: 'windowMenu' }
  {
    label: 'Window',
    submenu: [
      { role: 'minimize' },
      { role: 'zoom' },
      ...(isMac
        ? [
            { type: 'separator' },
            { role: 'front' },
            { type: 'separator' },
            { role: 'window' }
          ]
        : [
            { role: 'close' }
          ])
    ]
  },
  {
    role: 'help',
    submenu: [
      {
        label: 'Learn More',
        click: async () => {
          const { shell } = require('electron')
          await shell.openExternal('https://electronjs.org')
        }
      }
    ]
  },

  // 第一步看这个就可以
  {
    label: 'action',
    submenu: [
        {
            label: '添加(打开dialog)',
            click: () => {
                // 作用: 主进程通知渲染进程
                // 点击后主进程触发preload预加载内对应的事件,然后渲染进程触发打开弹窗
                event.sender.send('on-renderer-event', 'add')
            }
        }
    ]
  },
]

const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)



// preload.js处理主进程的事件event.sender.send('on-renderer-event', 'add')
const {ipcRenderer, contextBridge} = require('electron')

const openDialog = () => ipcRenderer.send('on-opendialog-event')

const onRendererEvent = () => {
    return new Promise((resolve, reject) => {
        ipcRenderer.on('on-renderer-event', (e, message) => {
            // 主进程通知后就触发这个回调
            resolve(message)
        })
    })
}

contextBridge.exposeInMainWorld('getSource', {
    openDialog,
    onRendererEvent
})



// 最后渲染进程Home.vue接收到传来的add,对类型进行监听后弹窗
<script setup lang="ts" name="Home">
    import {provide, ref, onMounted} from 'vue'

    let type = ref('');
   
    onMounted(async () => {
      window.getSource.openDialog()
      
      // 主进程触发preload,preload通知这里执行
      const res = await window.getSource.onRendererEvent()
      type.value = res;
    })

</script>

<template>
  <main>
    <div>home</div>
    <SearchBar :type="type" />
    <List />

  </main>
</template>


// Searbar.vue监听type的值
<script setup lang="ts" name="SearchBar">
    import {ref, inject, watch} from 'vue'
    import Dialog from './Dialog.vue'
    
    const props = defineProps(['type'])

    const {show, setShow} = inject('on-show-event', {show: false, setShow: () => {}})

    function handleShowDialog () {
        setShow()
    }

    // 这里监听
    watch(() => props.type, () => {
        if (props.type == 'add') {
            handleShowDialog();
        }
    })
</script>

<template>
  <div class="search_bar">
    <div @click="handleShowDialog">+</div>
    <input placeholder="请输入关键词" type="text">
  </div>

  <Dialog></Dialog>

</template>

<style lang="less" scoped>
    .search_bar {
        width: 100%;
        display: flex;
        align-items: center;
        height: 60px;
        background-color: #ccc;

        > div {
            margin-left: 20px;
            background-color: aqua;
            width: 16px;
            height: 16px;
            display: flex;
            align-items: center;
            justify-content: center;
            margin-right: 20px;
        }

        > input {
            flex: 1;
        }
    }
</style>

效果如下:

相关推荐
扎量丙不要犟9 小时前
跨平台的客户端gui到底是选“原生”还是web
前端·javascript·c++·qt·rust·electron·tauri
daqinzl1 天前
electron 应用开发实践
electron
Bigger2 天前
Tauri(十)—— 生产环境调试指南
前端·rust·electron
刘贤松4 天前
Mac Electron 应用签名(signature)和公证(notarization)
javascript·macos·electron
Dragon Wu4 天前
electron typescript运行并设置eslint检测
前端·javascript·typescript·electron·前端框架
Qlittleboy4 天前
Electron版本列表
前端·javascript·electron
爱上大树的小猪6 天前
【前端】Electron入门开发教程,从介绍Electron到基础引用以及部分深度使用,附带常见的十个报错问题的解决方案和代码优化。
前端·javascript·electron
这里是杨杨吖6 天前
SpringBoot+Electron教务管理系统 附带详细运行指导视频
spring boot·后端·electron·教务
Qlittleboy6 天前
Electron学习笔记,安装环境(1)
笔记·学习·electron
lxkj_20248 天前
electron打包客户端在rk3588上支持h265硬解
electron·视频编解码