Hi. I am trying to open a vue component in a new browserWindow when a user clicks a button. This works, but I had to create a new vue app which linked the pinia store from main.js to history.js. history.js open a view named History.vue. This means I have two html files. One index.html and one history.html. This works as expected, but as soon as I open the modal, Pinia store wont display the selectedId I got from home.vue. Its like the store is reset after I open the modal.
#Vue + Pinia + modal
46 messages · Page 1 of 1 (latest)
// main.js
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
secondaryWindow.loadURL(`${process.env['ELECTRON_RENDERER_URL']}/history.html`)
} else {
mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
secondaryWindow.loadFile(join(__dirname, '../renderer/history.html'))
}
// main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import router from './router'
import App from './App.vue'
export const app = createApp(App)
export const pinia = createPinia()
app.use(pinia).use(router).mount('#app')
// history.js
import { createApp } from 'vue'
import { pinia } from './main.js';
import History from '../src/views/History.vue'
import { useInboundStore } from './store/inboundStore.js'
const historyApp = createApp(History);
historyApp.use(pinia).mount('#history');
<!-- index.html -->
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
<title>Electron</title>
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self' http://localhost:8000; font-src 'self' https://fonts.gstatic.com/; style-src 'self' https://fonts.googleapis.com/ 'unsafe-inline';">
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
<!-- history.html -->
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
<title>Electron</title>
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self' http://localhost:8000; font-src 'self' https://fonts.gstatic.com/; style-src 'self' https://fonts.googleapis.com/ 'unsafe-inline';">
</head>
<body>
<div id="history"></div>
<script type="module" src="/src/history.js"></script>
</body>
</html>
Is this the wrong way of doing this or is there something I am doing wrong?
It feels a bit dumb to have two apps just for a modal, but I dont see any other way of doing this. I could create a modal as a vue component, but I want to use electron browserWindow
browser windows are separated from each other
if you want to have data from window a in window b you need to pass data
Thanks for your response. Could you give me an example of how I could pass the data from inboundStore between the two apps/windows? I would think creating the store inside main.js and then passing it to history.js would be enough.
i dont know what inboundStore is
but if you what to pass data from window a to window b you need ipc
// inboundStore.js
import { defineStore } from 'pinia'
import { ref } from 'vue'
const API_BASE_URL = 'http://localhost:8000';
export const useInboundStore = defineStore('inboundStore', {
state: () => ({
selectedInboundEntryId: ref(''),
inboundDeclaration: [],
inboundDeclarations: [],
currency: [],
currencyData: [],
selectedCurrencyId: ref(''),
officeData: [],
tradingPartners: [],
addPurchaseOrder: ref(false),
logs: []
}),
async getInboundDeclarationById(declarationId) {
try {
const response = await fetch(
`${API_BASE_URL}/inbound/get-declarations/${declarationId}`,
{
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
}
)
if (response.status === 200) {
this.inboundDeclaration = await response.json()
this.selectedInboundEntryId = this.inboundDeclaration._id
} else {
const errorData = await response.json()
console.log('Error fetching declarations:', errorData.error)
}
} catch (error) {
console.log('Error fetching declarations:', error.message)
}
},
It give me nothing
I am setting the selectedInboundEntry to this.inboundDeclaration._id before I go to History.vue.
in History.vue i am using this action to get the History data:
// inboundStore.js
async getLogsById(declarationId) {
try {
console.log(this.selectedInboundEntryId, "Entry ID")
const response = await fetch(
`${API_BASE_URL}/api/inbound/get-logs/${declarationId}`,
{
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
}
)
if (response.status === 200) {
this.logs = await response.json()
console.log(this.logs)
} else {
const errorData = await response.json()
console.log('Error fetching declarations:', errorData.error)
}
} catch (error) {
console.log('Error fetching declarations:', error.message)
}
},
// History.vue
<script setup>
import { useInboundStore } from '../store/inboundStore.js'
import { storeToRefs } from 'pinia';
import { onMounted, watch } from 'vue';
const inboundStore = useInboundStore();
const { inboundDeclaration, logs, selectedInboundEntryId, inboundDeclarations, currencyData, officeData } = storeToRefs(inboundStore);
onMounted( async () => {
await inboundStore.getLogsById(selectedInboundEntryId.value)
});
Sorry Discord dont allow me to paste everything :/
I don't know how pinia works
Its like vuex if that helps
I can sync data between the whole app. If i set this.selectedInboundEntryId in a component, it is persistent in whatever view or component I load the inboundStore
but as soon as I added another app the store is somehow reset. it doesnt even log undefined.
console.log(this.selectedInboundEntryId, "Entry ID")
// Logs Entry ID
Because every tab have its own store
Yes. I belive so. I have not used tabs, I am using a vue router in the main app and everything is synced.
Vue router just add fake navigation into web page
Data stay the same
GitHub
Hey all, I'm working on web version of a board game, and I've got my MVP up and running using Vue 3 and Vuex 4. I want to swap out my Vuex stores for Pinia so that I can rely on its Typescr...
Something like this
I might be both doing this the wrong way or overthinking the whole concept here, but electron-vite creates a main, preload and a renderer folder. Everything runs from the main.js inside the renderer. This means that all the parts in vue runs with a single .html file.
Every tutorial or docs I have seen online use different html files for different BrowserWindows. Thats what got me to where I am right now. Two Vue apps with two html files. This seems a bit like: "over comblicating things"
If you consider html file as separate app then yes
For me its another html file you can open in browser window
in SPA world you only have one html file
As entry point
And vue router show some parts of the app based on path or query
Something like this would make sense to me, but this wont work xD.
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
secondaryWindow.loadURL(`${process.env['ELECTRON_RENDERER_URL']}/src/views/History.vue`)
} else {
mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
secondaryWindow.loadFile(join(__dirname, '../renderer/src/views/History.vue'))
}
Maybe I should not use Vue and go back to Vanilla and create everything separately.
Without navigation
Save thing happens with vanilla js
That's how browser works
You need to sync data between them
Or pass data to new window
Thanks for all your help and patience yesterday. I tried to rewrite my project to Vanilla yesterday. It works as expected. I removed pinia store and used ipc to send the messages from the backend between windows. Now it works as expected.