欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue+electron實(shí)現(xiàn)創(chuàng)建多窗口及窗口間的通信(實(shí)施方案)

 更新時(shí)間:2022年09月06日 16:04:31   作者:做什么夢呢  
這篇文章主要介紹了vue+electron實(shí)現(xiàn)創(chuàng)建多窗口及窗口間的通信,本文給大家分享實(shí)施方案結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下

一、前言

對于一個(gè)桌面應(yīng)用來說,有時(shí)候單獨(dú)一個(gè)窗口用戶使用起來會(huì)不太方便,比方說寫日報(bào)或者查看文件等,若是在同一窗口內(nèi),我只能做一件事,不能邊預(yù)覽文件,邊去查看聊天消息內(nèi)容等。又或者是多個(gè)應(yīng)用間相互關(guān)聯(lián)的需要同步查看的事件,這都是極其不方便的。因此我們可以將某些集成到electron軟件中的應(yīng)用或者某些界面用單獨(dú)的窗口打開(以下稱為獨(dú)立窗口)。

二、實(shí)施方案

1.創(chuàng)建多窗口

首先我們從electron官網(wǎng)中找到創(chuàng)建窗口的方法,electron官網(wǎng)的BrowserWindow,接下來我們就簡單寫一個(gè)獨(dú)立窗口的創(chuàng)建。這個(gè)窗口可以打開外部應(yīng)用也可以是應(yīng)用內(nèi)部。

// windows/CreateIndependentWindow.js
import { BrowserWindow, globalShortcut, ipcMain } from 'electron'
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
// 關(guān)于這個(gè)插件,可以看下前幾天我寫的解決electron白屏那篇文章
import CreateProcessLoadingPage from './CreateProcessLoadingPage'
/**
 * 必傳參數(shù)
 * outUrl  外部鏈接
 * or
 * inUrl 內(nèi)部鏈接
 * windowTitle 頁面標(biāo)題 注意:此值不可重復(fù)
*/
const CreateIndependentWindow = ({
  ...data
}, win) => {
  const obj = {
    // 窗口的大小可以通過傳進(jìn)來的參數(shù)控制
    height: data.height || 640,
    width: data.width || 1024,
    show: false, // 初始是否可顯示
    center: true,
    // 窗口是否可以進(jìn)入全屏狀態(tài)
    fullscreenable: false, 
    closable: true, // 窗口是否可關(guān)閉
    resizable: true, // 禁止改變主窗口尺寸
    webPreferences: {
      nodeIntegration: true, // 啟用Node integration
      webSecurity: false,
      webviewTag: true, // 允許在頁面內(nèi)使用webview標(biāo)簽
      enableRemoteModule: true, // 允許渲染進(jìn)程使用remote模塊
      nodeIntegrationInWorker: true, // 在Web工作器中啟用了Node集成
      // 允許在子頁面(iframe)或子窗口(child window)中集成Node.js
      nodeIntegrationInSubFrames: true 
    }
  }
  // 這里創(chuàng)建窗口實(shí)例
  const independentWindow = new BrowserWindow(obj)
  // 注冊全局快捷鍵-打開開發(fā)者工具(方便查看問題)
  globalShortcut.register('CommandOrControl+alt+shift+l', () => {
    independentWindow.webContents.openDevTools()
  })
  // 設(shè)置窗口名稱
  independentWindow.setTitle(data.windowTitle || '人脈旺')
  // 這里將當(dāng)前窗口的唯一id,存入全局變量,以容易區(qū)分多個(gè)獨(dú)立窗口
  // 變量聲明下方說明
  global.sharedObject.independentWindow.set(data.windowTitle, independentWindow.webContents.id)
  // 聲明打開頁面的url
  let winURL = ''
  // /IndependentWindow這個(gè)路由是在渲染進(jìn)程創(chuàng)建的承載外部鏈接的獨(dú)立窗口的頁面
  if (process.env.WEBPACK_DEV_SERVER_URL) { // 判斷若為開發(fā)環(huán)境
    // independentWindow.webContents.openDevTools()
    winURL = process.env.WEBPACK_DEV_SERVER_URL + '#/' + (data.inUrl ? data.inUrl : 'IndependentWindow')
  } else {
    createProtocol('app')
    winURL = 'app://./index.html#' + (data.inUrl ? data.inUrl : '#/IndependentWindow')
  }
  // 這里是為了獲取拼接需要傳入到頁面的參數(shù)
  const param = Object.keys(data).reduce((pre, cue) => {
    return data[cue] ? `${pre}${pre === '?' ? '' : '&'}${cue}=${data[cue]}` : pre
  }, '?')
  // 使用loadURL方法將頁面注入到窗口
  independentWindow.loadURL(winURL + param)
  // 若參數(shù)設(shè)置開啟最大化窗口
  if (data.maxSize) {
    independentWindow.maximize()
  }
  // 加載頁面loading
  CreateProcessLoadingPage(independentWindow, data)

  independentWindow.on('close', (e) => {
    globalShortcut.unregister('CommandOrControl+alt+shift+l')
    global.sharedObject.independentWindow.delete(data.windowTitle)
    setTimeout(() => {
      if (!independentWindow.isDestroyed() && independentWindow) {
        independentWindow.destroy()
      }
    }, 100)
  })

  global['independentWindow-' + independentWindow.webContents.id] = independentWindow
}
export default CreateIndependentWindow

之后我們在主進(jìn)程中做一個(gè)監(jiān)聽,用來創(chuàng)建獨(dú)立窗口

ipcMain.on('createOtherWindow', (e, data) => { // type窗口類型,data 參數(shù)
    const name = data.windowTitle
    // 判斷當(dāng)前窗口是否已經(jīng)存在, 存在的話 直接喚起
    if (global.sharedObject.independentWindow.has(name)) {
        const id = global.sharedObject.independentWindow.get(name)
        global['independentWindow-' + id].show()
    } else {
        CreateIndependentWindow(data, win)
    }
})

這里我們記得聲明一下存儲(chǔ)獨(dú)立窗口id的變量

// background.js
// 多窗口數(shù)據(jù)存儲(chǔ)
global.sharedObject = {
   independentWindow: new Map(),
}

之后我們在渲染進(jìn)程創(chuàng)建一個(gè)頁面,用來展示外部鏈接頁面

<template>
  <div class="independent-window">
    <webview id="myWebView" :src="outUrl" style="display:inline-flex; width:100%; height:100%" allowpopups></webview>
  </div>
</template>

<script>
export default {
  name: 'IndependentWindow',
  data () {
    return {
      outUrl: '',
    }
  },
  created () {
    this.outUrl = this.$route.query.outUrl
  },
  mounted () {
    this.eventHandler()
  },
  methods: {
    // 監(jiān)聽打開webview控制臺(tái)的快捷鍵
    eventHandler () {
      const webview = document.querySelector('#myWebView')
      // 用于查看webview內(nèi)第三方應(yīng)用問題,快捷鍵打開webview的開發(fā)者工具
      window.addEventListener('keydown', e => {
        if (e.altKey && e.ctrlKey && e.shiftKey && e.keyCode === 190) {
          webview.openDevTools()
        }
      })
    }
  }
}
</script>
<style lang="less" scoped>
.independent-window {
  width: 100%;
  height: 100%;
}
</style>

綜上,我們就創(chuàng)建了一個(gè)獨(dú)立窗口,這個(gè)獨(dú)立窗口可以打開項(xiàng)目內(nèi)頁面又或者第三方外部鏈接窗口。

2.多窗口間的通信

electron官方文檔給我們提供了關(guān)于多個(gè)窗口間通訊的方法, 對于多窗口間的通訊,多是指渲染進(jìn)程間的通訊。 這里我們可以使用ipcRenderer.sendTo()這個(gè)方法,來進(jìn)行多窗口建的通信。詳見官方文檔說明

ipcRenderer.sendTo(webContentsId, channel, ...args)? 以下是官方文檔內(nèi)容

  • webContentsId number
  • channel string
  • ...args any[]

通過 channel 發(fā)送消息到帶有 webContentsId 的窗口.

這里就用到了我們之前在global.sharedObject.independentWindow中存儲(chǔ)的各個(gè)窗口的id。 劃重點(diǎn)一定是窗口實(shí)例的webContentsId的id,而不是窗口的id,別問我怎么知道的,問也不說??????。

// 窗口1中
const remote = window.require('electron').remote
// 通過窗口名獲取窗口id
const id = remote.getGlobal('sharedObject').independentWindow.get('窗口名windowTitle')
ipcRenderer.sendTo(id, '約定的通信協(xié)議', 參數(shù))

// ===========================-.-===========

// 在另一個(gè)窗口中
ipcRenderer.on('約定的通信協(xié)議', (e, url) => {
  //做你想做的
})

這樣我們就實(shí)現(xiàn)多窗口渲染進(jìn)程間的通訊。

三、后記

多窗口的場景有人多,有時(shí)候情況可能會(huì)很復(fù)雜,我建議可以將那些特殊作用的窗口,單獨(dú)創(chuàng)建一個(gè),而不是都放到通用的獨(dú)立窗口中,這樣管理起來會(huì)很方便。

到此這篇關(guān)于vue+electron實(shí)現(xiàn)創(chuàng)建多窗口及窗口間的通信的文章就介紹到這了,更多相關(guān)vue electron多窗口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue 微信授權(quán)登錄解決方案

    vue 微信授權(quán)登錄解決方案

    這篇文章主要介紹了vue 微信授權(quán)解決方案,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-04-04
  • antd upload上傳組件如何獲取服務(wù)端返回?cái)?shù)據(jù)

    antd upload上傳組件如何獲取服務(wù)端返回?cái)?shù)據(jù)

    這篇文章主要介紹了antd upload上傳組件如何獲取服務(wù)端返回?cái)?shù)據(jù)問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Vue3+vite路由配置優(yōu)化(自動(dòng)化導(dǎo)入)

    Vue3+vite路由配置優(yōu)化(自動(dòng)化導(dǎo)入)

    這篇文章主要介紹了Vue3+vite路由配置優(yōu)化(自動(dòng)化導(dǎo)入),需要的朋友可以參考下
    2023-09-09
  • vue按需加載實(shí)例詳解

    vue按需加載實(shí)例詳解

    在本篇文章里小編給大家整理的是關(guān)于vue按需加載實(shí)例的相關(guān)知識(shí)點(diǎn)內(nèi)容,有需要的朋友們可以學(xué)習(xí)參考下。
    2019-09-09
  • 使用vue-router在Vue頁面之間傳遞數(shù)據(jù)的方法

    使用vue-router在Vue頁面之間傳遞數(shù)據(jù)的方法

    這篇文章主要介紹了使用vue-router在Vue頁面之間傳遞數(shù)據(jù)的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • vue使用formData時(shí)候傳遞參數(shù)是個(gè)空值的情況處理

    vue使用formData時(shí)候傳遞參數(shù)是個(gè)空值的情況處理

    這篇文章主要介紹了vue使用formData時(shí)候傳遞參數(shù)是個(gè)空值的情況處理,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • vue中的v-slot指令使用

    vue中的v-slot指令使用

    在Vue中, v-slot 指令用于定義插槽的模板內(nèi)容,v-slot 指令可以用于標(biāo)簽或組件標(biāo)簽上,以便在子組件中使用插槽,這篇文章主要介紹了vue v-slot指令,需要的朋友可以參考下
    2023-08-08
  • vue實(shí)現(xiàn)表格數(shù)據(jù)的增刪改查

    vue實(shí)現(xiàn)表格數(shù)據(jù)的增刪改查

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)表格數(shù)據(jù)的增刪改查,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Vue el-table組件如何實(shí)現(xiàn)將日期格式化

    Vue el-table組件如何實(shí)現(xiàn)將日期格式化

    這篇文章主要介紹了Vue el-table組件如何實(shí)現(xiàn)將日期格式化問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • vue+element-ui+axios實(shí)現(xiàn)圖片上傳

    vue+element-ui+axios實(shí)現(xiàn)圖片上傳

    這篇文章主要為大家詳細(xì)介紹了vue+element-ui+axios實(shí)現(xiàn)圖片上傳,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08

最新評論