Electron app with Vue 3. Ubuntu 24.04 Chrome/98.0.4758.141 Electron/17.4.7 node v23.5.0 @vue/cli 5.0.8 vue@3.5.13
It reads a file from local disk and loads it into a reactive variable in Vue 3 so I can display data from it in the UI.
In the code below, the file contents is successfully read by the main process and is returned in the callback within the window.api.receive("fromMain" function. The console.log shows the expected contents of the file as a json string and is working as expected.
The problem I have is in the rendered template, the {{ pdata }} renders as "22222222", but I expect it to render as the text in the data variable, since the callback will get called after the 22222222 assignment.
Why doesn't this work? And what is the correct way to get it to work?
What I've tried:
App.vue:
<script setup>
import { ref } from 'vue'
let pdata = ref("1111111111")
pdata = "22222222"
window.api.receive("fromMain", (data) => {
console.log(`Received ${data}`)
pdata = data
})
// This triggers the file read in main
window.api.send("toMain", "some data")
</script>
<template>
{{ pdata }}
</template>
let pdata = ref("1111111111")
pdata = "22222222" // No longer a ref ❌
The second statement is a complete reassignment from pdata
being a reactive ref object to a plain (non-reactive) string. It's recommended that refs always be defined with const
, because they should never be reassigned, and it would prevent this exact mistake. The correct way to assign a new value while maintaining reactivity is to assign to the .value
property of the ref object:
const pdata = ref("1111111111")
pdata.value = "22222222" // Reassigns "inner" value of ref ✅
For convenience, you do not need to reference .value
in template code (it's done automatically). This is still fine:
<template>
{{ pdata }}
</template>