Electron is an app framework to let us build desktop apps that are based on web apps.
The apps are cross-platform and are rendered with the Chromium browser engine.
We can use the vue-cli-plugin-electron-builder code generator to build an Electron app based on Vue.js.
In this article, we’ll look at how to build a simple Electron Vue app.
Getting Started
We can get started by creating a Vue.js project.
To do that, we create an empty project folder, go into it, and run:
npx vue create .
Then we follow the instructions to add the items we want.
Next, we run the Vue CLI Plugin Electron Builder generator to add the Electron files to our Vue app.
We run:
vue add electron-builder
to add all the files and settings automatically.
Then to start the dev server, we run:
yarn electron:serve
or
npm run electron:serve
We should see a Window for our app displayed.
The dev console should also be shown.
Now we just have to write our Vue app.
Writing the Code
We write the code like any other Vue app.
In App.vue
, we write:
<template>
<div id="app">
<form @submit.prevent="add">
<input type="text" v-model="todo" />
<input type="submit" value="add" />
</form>
<div v-for="(t, i) of todos" :key="t.id">
{{t.todo}}
<button @click="remove(i)">remove</button>
</div>
</div>
</template>
<script>
import { v4 as uuidv4 } from "uuid";
export default {
name: "App",
data() {
return {
todo: "",
todos: [],
};
},
methods: {
add() {
this.todos.push({ id: uuidv4(), todo: this.todo });
this.todo = "";
},
remove(index) {
this.todos.splice(index, 1);
},
},
};
</script>
to add a todo list into our app.
We have a form to add the todo list.
Then we have the add
method to add an entry to this.todos
.
We create unique IDs for each entry with the uuid
NPM package, which we install by running:
npm i uuid
And we have the remove
to remove the this.todos
entry with the given index.
In the form with listen to the submit
event with the @submit.prevent
directive to also call preventDefault
to prevent default submission behavior.
Now we should see our todo app displaying in the window.
Build Our App
To build our app into an executable file, we run:
yarn electron:build
with Yarn or:
npm run electron:build
with NPM.
Native Modules
We can add native modules into our app within the vue.config.js
file:
module.exports = {
pluginOptions: {
electronBuilder: {
externals: ['my-native-dep'],
nodeModulesPath: ['../../node_modules', './node_modules']
}
}
}
We can add the node_module
paths for location the modules.
externals
is for listing names of modules that don’t work with our app.
Web Workers
To add workers, we add them to the vue.config.js
file by writing:
const WorkerPlugin = require('worker-plugin')
module.exports = {
configureWebpack: {
plugins: [new WorkerPlugin()]
}
}
We install the worker-plugin
package by running:
npm i worker-plugin
Now we can use worker files by writing:
src/worker.js
onmessage = (e) => {
const { a, b } = e.data;
const workerResult = +a + +b;
postMessage(workerResult);
}
src/App.vue
<template>
<div id="app">
<form @submit.prevent="send">
<input type="text" v-model="a" />
<input type="text" v-model="b" />
<input type="submit" value="add" />
</form>
<p>result: {{result}}</p>
</div>
</template>
<script>
const worker = new Worker("./worker.js", { type: "module" });
export default {
name: "App",
data() {
return {
a: 0,
b: 0,
result: 0
};
},
mounted() {
worker.onmessage = this.onMessage;
},
methods: {
send() {
const { a, b } = this;
worker.postMessage({ a, b });
},
onMessage({data}) {
this.result = data;
},
},
};
</script>
We created a worker that listens to the message
event.
The message
event is emitted by the worker.postMessage
method that we emit in the send
method.
send
gets the data from what we typed in.
Once the message
event is emitted, then we get the data sent from e.data
.
Then we compute the result and call postMessage
to send the computed result back to App.vue
.
App.vue
gets the result from the onMessage
method.
And we display the result
from it.
Conclusion
We can create a desktop app with Vue.js with the vue-cli-plugin-electron-builder generator.
It has support for web workers.