What is Electron?
This implies that if you have prior familiarity working with these technologies, you can use the same codebase to develop a desktop application for Windows, Linux, and macOS. Behind the scenes, Electron combines the Chromium engine with Node.js runtime to read and run your codebase as a standalone desktop program.
And, to prove its capabilities, popular desktop programs created using Electron include Slack, VS Code, and WhatsApp Desktop. The following are some of the advantages of using Electron:. Single codebase — With Electron, you’ll only need a single codebase to create desktop applications for different operating systems.
Experience your Vue apps exactly how a user does
- Just like anything else, there are some downsides to building desktop applications with Electron too. Some of them include:.
- Higher resource consumption — Desktop applications written in Electron are known to consume more CPU and RAM compared to apps written in other environments, such as Java FX, Objective C, and so on.
- Larger app size — As previously stated, Electron applications bundle the Chromium engine during the build process, which results in a big app size even for a simple application.
Building our movie app
If you’ve worked with Vue before, it’s fairly simple to get started with Electron. This is possible with a Vue CLI plugin called Electron Builder, and in the coming sections, we’ll learn how this plugin works by building a sample application that returns a wholesome list of trending movies from themoviedb API.
Here is a preview of what our movie application will look like:. Since Electron builder is a Vue CLI plugin. This means we’ll need to install the Vue CLI itself before we can work with it. To do this run:. Running the above command will install the most recent stable version of Vue CLI, and you can verify that it was successful by running vue -V, which should print out the installed version of Vue.
Next, we want to create a new Vue application, so go ahead and run the command below to create a new app named vue-desktop:. The final step is to add the Vue Electron Builder plugin, and we can do this by running the command below:. This will ask you for the version of Electron you want to add to this Vue project, and once you’ve done so, you should see a success message indicating that Electron Builder was installed.
You can then launch the app by running:. And you should see an output similar to the screenshot below:.
Closing the dev tool, you should see the complete preview of the application, like in the image below:. When you open the project folder in your preferred text editor, you should be presented with the following files and directory as shown in the image below. And if you’ve worked with Vue CLI in the past, you will notice that the file structure is pretty much the same.
The only change is the addition of a new background.js file, and this file is responsible for running our Vue application as a stand-alone desktop application. In this file, you can configure the default width and height of the window the application launches with, set the application title, add an auto-update feature, among other things.
Now that we’re up to speed with Vue Electron Builder, let’s go ahead and start building our trending movie application.
Next, in the src/components folder, create a new file called MovieCard.vue and paste the following code into it:. Here, we have created a MovieCard component that accepts a prop containing all of the details for each movie. The next step is to delete all of the code contained in src/App.vue and update with the following:. At this point, if we run our application, we should have the following output:. The final step is to define a method that fetches the most popular movies from the TMDB API. This process would require you to create a free account with them to retrieve your API key. To do this, update src/App.vue with the following code:.
Here, we imported the MovieCard component we created earlier in the script section, and we also added a new method, getTrendingMovies(), which is responsible for loading our movies from TMDB API, and we then ran this function in the mounted hook.
And a small change to our markup is looping all of the results returned from TMDB into our MovieCard component.
If we refresh our application at this stage, everything should work fine, and you should have an output similar to the image below:. The Electron icon is set as the default icon for your app, and most of the time, you’ll probably want to set your custom icon.
You can simply update the app icon by adding a new icon entry in the newBrowserWindow() method present in background.js like below:.
Compiling our application as a stand-alone executable file is straightforward. We can do so by running the command below:. Keep in mind the executable app that is generated is dependent on the operating system you’re working with.
However, Electron Builder allows you to define which platform (or platforms) you want to generate executables for. Available options include Mac, Win, and Linux.
This means to build the Linux version of your applications, you’ll run the following command:.
Declaring Reactive Properties
Throughout this tutorial, we’ve looked at how to use Electron and Vue to create a cross-platform desktop application. We also built an example trending movies application to understand how things worked.
And the code for the complete application can be found here on GitHub. If you enjoy reading the article, do leave a comment below! You’re browsing the documentation for v2.x and earlier. For v3.x, click here. Now it’s time to take a deep dive! One of Vue’s most distinct features is the unobtrusive reactivity system.
Building the app
This is an ES5-only and un-shimmable feature, which is why Vue doesn’t support IE8 and below. The getter/setters are invisible to the user, but under the hood they enable Vue to perform dependency-tracking and change-notification when properties are accessed or modified.
One caveat is that browser consoles format getter/setters differently when converted data objects are logged, so you may want to install vue-devtools for a more inspection-friendly interface.
Every component instance has a corresponding watcher instance, which records any properties “touched” during the component’s render as dependencies.
However, there are ways to circumvent them to preserve reactivity. Vue cannot detect property addition or deletion.
Since Vue performs the getter/setter conversion process during instance initialization, a property must be present in the data object in order for Vue to convert it and make it reactive.
Vue does not allow dynamically adding new root-level reactive properties to an already created instance.
However, it’s possible to add reactive properties to a nested object using the Vue.set(object, propertyName, value) method:. You can also use the vm.$set instance method, which is an alias to the global Vue.set:. Sometimes you may want to assign a number of properties to an existing object, for example using Object.assign() or _.extend().
However, new properties added to the object will not trigger changes. In such cases, create a fresh object with properties from both the original object and the mixin object:. Vue cannot detect the following changes to an array:. When you directly set an item with the index, e.g.
vm.items[indexOfItem] = newValue. When you modify the length of the array, e.g. vm.items.length = newLength. To overcome caveat 1, both of the following will accomplish the same as vm.items[indexOfItem] = newValue, but will also trigger state updates in the reactivity system:.
Change Detection Caveats
You can also use the vm.$set instance method, which is an alias for the global Vue.set:. To deal with caveat 2, you can use splice:.
Since Vue doesn’t allow dynamically adding root-level reactive properties, you have to initialize Vue instances by declaring all root-level reactive data properties upfront, even with an empty value:. If you don’t declare message in the data option, Vue will warn you that the render function is trying to access a property that doesn’t exist.
There are technical reasons behind this restriction - it eliminates a class of edge cases in the dependency tracking system, and also makes Vue instances play nicer with type checking systems. But there is also an important consideration in terms of code maintainability: the data object is like the schema for your component’s state. Declaring all reactive properties upfront makes the component code easier to understand when revisited later or read by another developer.
In case you haven’t noticed yet, Vue performs DOM updates asynchronously. Whenever a data change is observed, it will open a queue and buffer all the data changes that happen in the same event loop. If the same watcher is triggered multiple times, it will be pushed into the queue only once. This buffered de-duplication is important in avoiding unnecessary calculations and DOM manipulations.
Then, in the next event loop “tick”, Vue flushes the queue and performs the actual (already de-duped) work. Internally Vue tries native Promise.then, MutationObserver, and setImmediate for the asynchronous queuing and falls back to setTimeout(fn, 0). For example, when you set vm.someData = 'new value', the component will not re-render immediately. It will update in the next “tick”, when the queue is flushed. Most of the time we don’t need to care about this, but it can be tricky when you want to do something that depends on the post-update DOM state.
Although Vue.js generally encourages developers to think in a “data-driven” fashion and avoid touching the DOM directly, sometimes it might be necessary to get your hands dirty. In order to wait until Vue.js has finished updating the DOM after a data change, you can use Vue.nextTick(callback) immediately after the data is changed.
Vue + Electron
The callback will be called after the DOM has been updated. There is also the vm.$nextTick() instance method, which is especially handy inside components, because it doesn’t need global Vue and its callback’s this context will be automatically bound to the current Vue instance:. Since $nextTick() returns a promise, you can achieve the same as the above using the new ES2017 async/await syntax:.
Caught a mistake or want to contribute to the documentation?Edit this on GitHub!Deployed onNetlify . Now it's time to dive deeper into Vue, and create our own custom component — we'll start by creating a component to represent each item in the todo list. Along the way, we'll learn about a few important concepts such as calling components inside other components, passing data to them via props, and saving data state.
Let's create our first component, which will display a single todo item. We'll use this to build our list of todos. In your moz-todo-vue/src/components directory, create a new file named ToDoItem.vue.
Create the component's template section by adding to the top of the file.
Create a section below your template section. Inside the