Kaynağa Gözat

addon window

gaoshuaixing 3 yıl önce
ebeveyn
işleme
1b93f30b06

+ 23 - 13
electron/controller/example.js

@@ -225,24 +225,34 @@ class ExampleController extends Controller {
     }
 
     console.log('url:', content);
+    const addonWindow = this.app.addon.window;
+    let opt = {
+      title: args.windowName || 'new window'
+    }
+    const name = args.windowName || 'window-1';
+    const win = addonWindow.create(name, opt);
+    const winContentsId = win.webContents.id;
 
-    let winObj = new BrowserWindow({
-      x: 10,
-      y: 10,
-      width: 980, 
-      height: 650,
-      title: 'new window',
-      webPreferences: {
-        contextIsolation: false,
-        nodeIntegration: true,
-      },
-    })
-    winObj.loadURL(content);
+    // load page
+    win.loadURL(content);
 
-    return winObj.id
+    return winContentsId
   }
   
   /**
+   * 获取窗口contents id
+   */
+  getWCid (args) {
+    const addonWindow = this.app.addon.window;
+
+    // 主窗口的name默认是main,其它窗口name开发者自己定义
+    const name = args;
+    const id = addonWindow.getWCid(name);
+
+    return id;
+  }
+
+  /**
    * 加载扩展程序
    */
   // async loadExtension (args) {

+ 10 - 1
frontend/src/api/main.js

@@ -1,6 +1,9 @@
 import storage from 'store2'
 import request from '@/utils/request'
 
+/**
+ * 路由定义(主进程与渲染进程通信频道定义)
+ */
 const ipcApiRoute = {
   test: 'controller.example.test',
   messageShow: 'controller.example.messageShow',
@@ -28,11 +31,17 @@ const ipcApiRoute = {
   ipcInvokeMsg: 'controller.example.ipcInvokeMsg',
   ipcSendSyncMsg: 'controller.example.ipcSendSyncMsg',
   ipcSendMsg: 'controller.example.ipcSendMsg',
+  getWCid: 'controller.example.getWCid',
   hello: 'controller.example.hello',
 }
 
+/**
+ * 特殊的路由(频道)定义
+ */
 const specialIpcRoute = {
-  appUpdater: 'app.updater' // 此频道在后端也有相同定义
+  appUpdater: 'app.updater', // 此频道在后端也有相同定义
+  window1ToWindow2: 'window1-to-window2', // 窗口之间通信
+  window2ToWindow1: 'window2-to-window1', // 窗口之间通信
 }
 
 /**

+ 1 - 1
frontend/src/config/router.config.js

@@ -127,7 +127,7 @@ export const constantRouterMap = [
       {
         path: 'subwindow',
         name: 'SpecialSubwindowIpc',
-        component: () => import('@/views/special/subwindow/Ipc')
+        component: () => import('@/views/base/subwindow/Ipc')
       }
     ]
   },

+ 39 - 2
frontend/src/views/base/socket/Ipc.vue

@@ -39,18 +39,39 @@
         <a-button @click="sendMsgStop">结束</a-button>
         结果:{{ messageString }}
       </a-space>
+    </div>
+    <div class="one-block-1">
+      <span>
+        4. 多窗口通信:子窗口与主进程通信,子窗口互相通信
+      </span>
     </div>  
+    <div class="one-block-2">
+      <a-space>
+        <a-button @click="createWindow(0)">打开新窗口2</a-button>
+        <a-button @click="sendTosubWindow()">向新窗口2发消息</a-button>
+      </a-space>
+    </div>      
   </div>
 </template>
 <script>
-import { ipcApiRoute } from '@/api/main'
+import { ipcApiRoute, specialIpcRoute } from '@/api/main'
 export default {
   data() {
     return {
       messageString: '',
       message1: '',
       message2: '',
-      message3: ''
+      message3: '',
+      windowName: 'window-1',
+      newWcId: 0,
+      views: [
+        {
+          type: 'vue',
+          content: '/special/subwindow',
+          windowName: 'window-1',
+          windowTitle: 'new window'
+        },    
+      ],
     }
   },
   mounted () {
@@ -68,6 +89,12 @@ export default {
         // 调用后端的另一个接口
         event.sender.send(ipcApiRoute.hello, 'electron-egg');
       })
+
+      // 监听 窗口2 发来的消息
+      this.$ipc.removeAllListeners(specialIpcRoute.window2ToWindow1);
+      this.$ipc.on(specialIpcRoute.window2ToWindow1, (event, arg) => {
+        this.$message.info(arg);
+      })
     },
     sendMsgStart() {
       const params = {
@@ -99,6 +126,16 @@ export default {
       const msg = this.$ipcSendSync(ipcApiRoute.ipcSendSyncMsg, '同步');
       this.message3 = msg;
     },
+    createWindow (index) {
+      this.$ipcInvoke(ipcApiRoute.createWindow, this.views[index]).then(id => {
+        console.log('[createWindow] id:', id);
+      })
+    },
+    async sendTosubWindow () {
+      // 新窗口id
+      this.newWcId = await this.$ipcInvoke(ipcApiRoute.getWCid, this.windowName);
+      this.$ipc.sendTo(this.newWcId, specialIpcRoute.window1ToWindow2, '窗口1通过 sendTo 给窗口2发送消息');
+    },
   }
 }
 </script>

+ 142 - 0
frontend/src/views/base/subwindow/Ipc.vue

@@ -0,0 +1,142 @@
+<template>
+  <div id="app-base-socket-ipc">
+    <div class="one-block-1">
+      <span>
+        1. 发送异步消息
+      </span>
+    </div>  
+    <div class="one-block-2">
+      <a-space>
+        <a-button @click="handleInvoke">发送 - 回调</a-button>
+        结果:{{ message1 }}
+      </a-space>
+      <p></p>
+      <a-space>
+        <a-button @click="handleInvoke2">发送 - async/await</a-button>
+        结果:{{ message2 }}
+      </a-space>            
+    </div>   
+    <div class="one-block-1">
+      <span>
+        <!-- 尽量不要使用,任何错误都容易引起卡死 -->
+        2. 同步消息(不推荐,阻塞执行)
+      </span>
+    </div>  
+    <div class="one-block-2">
+      <a-space>
+        <a-button @click="handleSendSync">同步消息</a-button>
+        结果:{{ message3 }}
+      </a-space>   
+    </div>        
+    <div class="one-block-1">
+      <span>
+        3. 长消息: 服务端持续向前端页面发消息
+      </span>
+    </div>  
+    <div class="one-block-2">
+      <a-space>
+        <a-button @click="sendMsgStart">开始</a-button>
+        <a-button @click="sendMsgStop">结束</a-button>
+        结果:{{ messageString }}
+      </a-space>
+    </div>
+    <div class="one-block-1">
+      <span>
+        4. 多窗口通信:窗口之间互相通信
+      </span>
+    </div>  
+    <div class="one-block-2">
+      <a-space>
+        <a-button @click="sendTosubWindow()">向主窗口发消息</a-button>
+      </a-space>
+    </div>       
+  </div>
+</template>
+<script>
+import { ipcApiRoute, specialIpcRoute } from '@/api/main'
+export default {
+  data() {
+    return {
+      messageString: '',
+      message1: '',
+      message2: '',
+      message3: '',
+      mainWCid: 0,
+    }
+  },
+  mounted () {
+    this.init();
+  },
+  methods: {
+    init () {
+      const self = this;
+      // 避免重复监听,或者将 on 功能写到一个统一的地方,只加载一次
+      this.$ipc.removeAllListeners(ipcApiRoute.ipcSendMsg);
+      this.$ipc.on(ipcApiRoute.ipcSendMsg, (event, result) => {
+        console.log('[ipcRenderer] [socketMsgStart] result:', result);
+
+        self.messageString = result;
+        // 调用后端的另一个接口
+        event.sender.send(ipcApiRoute.hello, 'electron-egg');
+      })
+
+      // 监听主窗口发来的消息
+      this.$ipc.removeAllListeners(specialIpcRoute.window1ToWindow2);
+      this.$ipc.on(specialIpcRoute.window1ToWindow2, (event, arg) => {
+          this.$message.info(arg);
+      })
+    },
+    sendMsgStart() {
+      const params = {
+        type: 'start',
+        content: '开始'
+      }
+      this.$ipc.send(ipcApiRoute.ipcSendMsg, params)
+    },
+    sendMsgStop() {
+      const params = {
+        type: 'end',
+        content: ''
+      }
+      this.$ipc.send(ipcApiRoute.ipcSendMsg, params)
+    },
+    handleInvoke () {
+      const self = this;
+      this.$ipcInvoke(ipcApiRoute.ipcInvokeMsg, '异步-回调').then(r => {
+        console.log('r:', r);
+        self.message1 = r;
+      });
+    },
+    async handleInvoke2 () {
+      const msg = await this.$ipcInvoke(ipcApiRoute.ipcInvokeMsg, '异步');
+      console.log('msg:', msg);
+      this.message2 = msg;
+    },
+    handleSendSync () {
+      const msg = this.$ipcSendSync(ipcApiRoute.ipcSendSyncMsg, '同步');
+      this.message3 = msg;
+    },
+    sendTosubWindow () {
+      // 获取主窗口id
+      this.$ipcInvoke(ipcApiRoute.getWCid, 'main').then(id => {
+        this.mainWCid = id;
+        this.$ipc.sendTo(this.mainWCid, specialIpcRoute.window2ToWindow1, '窗口2 通过 sendTo 给主窗口发送消息');
+      });
+    },
+  }
+}
+</script>
+<style lang="less" scoped>
+#app-base-socket-ipc {
+  padding: 0px 10px;
+  text-align: left;
+  width: 100%;
+  .one-block-1 {
+    font-size: 16px;
+    padding-top: 10px;
+  }
+  .one-block-2 {
+    padding-top: 10px;
+  }
+}
+</style>

+ 1 - 1
frontend/vue.config.js

@@ -12,7 +12,7 @@ module.exports = {
       config
         .plugin('html')
         .tap(args => {
-          args[0].title= 'EE框架' // 设置title
+          //args[0].title= '' // 设置title
           return args
         })
     },