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.