Electron-vue: Create a child browser window as a child Vue component?

Created on 11 Aug 2016  ·  7Comments  ·  Source: SimulatedGREG/electron-vue

This isn't an issue with the boilerplate itself but a general question working with Vue and Electron together (I'm new to both technologies). Is it possible to spawn a child browser window as a child Vue component from the main application?

Basically my main Vue app is logging financial data, I want to add a button that would create a child modal that takes the data as a prop then charts it. However, I have no clue how to approach I'd like to hear how someone would handle this having experience with both technologies.

From https://github.com/electron/electron/blob/master/docs/api/frameless-window.md

Creating a new window:

const {BrowserWindow} = require('electron')
let win = new BrowserWindow({width: 800, height: 600, frame: false})
win.show()

How would I wrap this into a single file .vue component, how would I share state between two browser windows (if it is even possible)?

question

Most helpful comment

@dlai286

Sorry for closing, didn't mean to... (I honestly think I must have hit the button when I put my phone in my pocket. 😂)

Anyways...

How would I wrap this into a single file .vue component

Since opening another BrowserWindow requires you to set a URL to load, you could either point to the same index.html as your main app and just point to a different route (if you are using vue-router) or you could modify webpack.config.js to bundle another index & js file specifically for that new BrowserWindow and then point to that new file. Doing so would require knowledge about creating another webpack output and knowledge of the html-webpack-plugin to define another .html file. Either method isn't really friendly.

There really isn't a way to pass data as a prop to another vue component that lives in another BrowserWindow. Trying to get this working is like trying to pass a prop to another tab if you were in a web browser, it just isn't possible. You could look into the default JS window.open api and see if you could pass data through. The only disadvantage here would be that electron doesn't let you set BrowserWindow options when using window.open as it uses the same options from it's parent.

how would I share state between two browser windows (if it is even possible)

Sharing data between multiple BrowserWindows really isn't the easiest thing at all, even with just electron itself (not using Vue). There are a few things you could try to implement, but they can be some what of a pain to maintain.

  1. Use LocalStorage to sync data between the separate windows (probably best case).
  2. Use the electron IPC apis to communicate between the separate windows (gets disorganized rather quickly).
  3. If you are using vuex, you might want to try setting that up in the main process. Doing this would let you expose your vuex datastore(s) globally to all renderer processes, therefore creating a _shared state_. (works in theory, haven't seen this actually done before).

My best advice...

I would try to avoid these situation that require data to be shared with another window. Many large electron apps including Slack, Discord, and others usually use standard pop-up modals in the same BrowserWindow to avoid jumping through these cumbersome hoops. I hope this helps 🙂

All 7 comments

@dlai286

Sorry for closing, didn't mean to... (I honestly think I must have hit the button when I put my phone in my pocket. 😂)

Anyways...

How would I wrap this into a single file .vue component

Since opening another BrowserWindow requires you to set a URL to load, you could either point to the same index.html as your main app and just point to a different route (if you are using vue-router) or you could modify webpack.config.js to bundle another index & js file specifically for that new BrowserWindow and then point to that new file. Doing so would require knowledge about creating another webpack output and knowledge of the html-webpack-plugin to define another .html file. Either method isn't really friendly.

There really isn't a way to pass data as a prop to another vue component that lives in another BrowserWindow. Trying to get this working is like trying to pass a prop to another tab if you were in a web browser, it just isn't possible. You could look into the default JS window.open api and see if you could pass data through. The only disadvantage here would be that electron doesn't let you set BrowserWindow options when using window.open as it uses the same options from it's parent.

how would I share state between two browser windows (if it is even possible)

Sharing data between multiple BrowserWindows really isn't the easiest thing at all, even with just electron itself (not using Vue). There are a few things you could try to implement, but they can be some what of a pain to maintain.

  1. Use LocalStorage to sync data between the separate windows (probably best case).
  2. Use the electron IPC apis to communicate between the separate windows (gets disorganized rather quickly).
  3. If you are using vuex, you might want to try setting that up in the main process. Doing this would let you expose your vuex datastore(s) globally to all renderer processes, therefore creating a _shared state_. (works in theory, haven't seen this actually done before).

My best advice...

I would try to avoid these situation that require data to be shared with another window. Many large electron apps including Slack, Discord, and others usually use standard pop-up modals in the same BrowserWindow to avoid jumping through these cumbersome hoops. I hope this helps 🙂

No worries man, I was a little taken aback when I saw it closed without explanation haha.

Thanks for the in-depth explanation, I think I will take your advice and just go for modal method. Using LocalStorage is a pretty nifty approach but doing constant reads in the high megabyte range might not be performant. Basically we wanted to play around with overlaying transparent browser windows with charting data on top of our ugly Java/C# tools.

Cheers for the info again!

Hi @idubz33. Did you get it to work? I'm trying to achieve the same goal using vue-router but I'm not getting it. I always get the error "Cannot GET /" when I call my second route.
Thank you for any help!

Hello guys,

I'm relatively new to this Electron and Vue world, and I hope they can help.

I'm developing an application that really needs a new window, it must be opened through a screen action (a button click), and it should open in the client's second monitor in fullscreen mode, this is already working (code below). The function is called by a Vue method in annother section.

But the problem is, the html is being included in the URL itself, because it was the only functional method I have found so far, but for me it is not useful, since I need to include some requirements (libraries, jQuery and others) in this window.

@SimulatedGREG commented on creating a new output in webpack, I believe it is the best solution, but I do not understand much of webpack, could anyone help me with this?

Do not need to include Vue in this remote window, just run javascript (ES6) in order to import the required libraries.

/ * ----- External screen control ----- * /

Let extwin = null;

Function liveWindow () {

If (extwin) {
// if the screen has opened, close it and assign null to your room.
Extwin.close (); Extwin = null;
Return;
}

Const path = require ('path');
Const url = require ('url');

Var electronScreen = require ('electron').
Var displays = electronScreen.getAllDisplays ();

Var externalDisplay = null;
For (var i in displays) {
If (displays [i] .bounds.x! = 0 || displays [i] .bounds.y! = 0) {
ExternalDisplay = displays [i];
Break;
}
}

Const remote = require ('electron').
Const BrowserWindow = remote.BrowserWindow;

If (externalDisplay) {
Extwin = new BrowserWindow ({
X: externalDisplay.bounds.x + 50,
Y: externalDisplay.bounds.y + 50,
Frame: false
});
Extwin.setFullScreen (true);

Var html = `
<Html>
<Head>
</ Head>
  <Body>
    <H1> It works </ h1>
  </ Body>
</ Html>
  `
Extwin.loadURL ("data: text / html; charset = utf-8," + encodeURI (html));

}
}

@AlexVFornazieri This helps out majorly with some stuff I've been trying to do. Thanks!

@benlipp
I'm glad to have helped,

I'm working on a part of my project that best solves this problem, something with two main renderer with fully functional Webpack in both.

Soon I'll create a sample repository and I'll post it here.

Hi @AlexVFornazieri ,
Did u post the example ?

Was this page helpful?
0 / 5 - 0 ratings