实现思路:渲染进程页面初始化后就通知主进程,然后把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>
效果如下: