Electron+Vue+Bootstrapでアプリ開発、前回の準備に続いて、実装編です。
今回は画面遷移や簡単なイベント処理をやってみたいと思います!
準備編は以下を参照ください^ ^
画面遷移
それでは早速やってみましょう!
まずは画面遷移から。
画面遷移はvue-routerを利用して行います。
とりあえずお試し用の簡単な画面を作成します。
src/views/Test.vueというファイルを作成し、以下の通り記述します。
<template>
<b-container>
<b-alert show>Test Page</b-alert>
</b-container>
</template>
次はrouterの定義に先ほどの作成した画面の定義を加えます。
routerのファイルはsrc/router/index.jsです。
以下の通り/testにアクセスしたら、Test.vueに遷移するような定義を追記します。
import Vue from "vue";
import VueRouter from "vue-router";
import Home from "../views/Home.vue";
Vue.use(VueRouter);
const routes = [
{
path: "/",
name: "Home",
component: Home,
},
{
path: "/about",
name: "About",
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () =>
import(/* webpackChunkName: "about" */ "../views/About.vue"),
},
// ---- 追記部分ここから ----
{
path: "/test",
name: "Test",
component: () =>
import("../views/Test.vue"),
},
// ---- 追記部分ここまで ----
];
const router = new VueRouter({
mode: "history",
base: process.env.BASE_URL,
routes,
});
export default router;
これで画面遷移の設定は完了です。
最後は画面遷移するためのリンクを作成します。
お試しなので、App.vueにリンクを加えてみましょう。
route-linkタグのto属性にrouterで定義したパスを指定します。
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link> |
<router-link to="/test">Test</router-link><!-- 追加 -->
</div>
<router-view />
</div>
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
}
#nav a {
font-weight: bold;
color: #2c3e50;
}
#nav a.router-link-exact-active {
color: #42b983;
}
</style>
上記までできたら画面を起動!
トップページにTestリンクが追加されてますね。これをクリックすると・・・

作成したTestページに遷移しました!

イベント処理
次はボタンのクリックしたときなどのイベント処理です。
処理を実装する前に知っておくべきなのが、メインプロセスとレンダープロセスです。
メインプロセスとレンダープロセス
Electronにはメインプロセスとレンダープロセスなるものがあり、主に以下のよう特徴があります。
メインプロセス
- アプリの起動・終了
- Node.jsでできることはほぼ何でもできる
- OSが持つ機能も活用可能
- アプリケーション全体で一つしか存在しない
レンダープロセス
- 画面の表示やインタフェースを担当
- ブラウザができる範囲のことしかできない
- アプリケーション内で複数存在する
- レンダープロセス間の通信はできない
基本的に画面のイベント処理はレンダープロセスで行うのですが、ブラウザでできない範囲の処理(ローカルにファイルを吐き出すなど)はメインプロセスとプロセス間で通信する必要があります。
ブラウザとWebサーバみたいな関係ですね(´▽`)
このプロセス間通信をIPC通信といいます。
IPC通信
IPC通信とはInter-Process Communicationの略で、プロセス間通信のことです。
Electronでは前述した、メインプロセスとレンダープロセス間の通信を指します。
メインプロセス、レンダープロセスにそれぞれにIPC通信を行うためのモジュールが用意されているため、それを利用して実現します。
- メインプロセス・・・ipcMain
- レンダープロセス・・・ipcRenderer
使い方は実装例にて。
実装例
それではイベント処理の実装例をやっていきましょう!
画面作成
まずは画面遷移で作成したTest.vueを以下のようなフォーム画面に書き換えます。
ボタンクリックなどのイベント処理はvueのお作法に従って実装すればOKです。
この画面上で動いている処理がレンダープロセス上の処理となります。
<template>
<b-form @submit="onSubmit" @reset="onReset">
<b-form-group label="Name:" label-for="input-name">
<b-form-input id="input-name" v-model="form.name"></b-form-input>
</b-form-group>
<b-form-group label="Age:" label-for="input-age">
<b-form-input id="input-age" v-model="form.age"></b-form-input>
</b-form-group>
<b-button type="submit" variant="primary">Submit</b-button>
<b-button type="reset" >Reset</b-button>
</b-form>
</template>
<script>
export default {
data() {
return {
form: {
name: '',
age: ''
}
}
},
methods: {
onSubmit(event) {
event.preventDefault();
console.log(this.form);
},
onReset(event) {
event.preventDefault();
this.form.name = '';
this.form.age = '';
}
}
}
</script>
上記画面は以下のような動作をします。
- submitボタンを押下→フォームの値をログに表示
- resetボタンクリック→フォームをクリア
ちなみにこの処理はブラウザ上で動いているため、ログはブラウザに表示されます。
動作確認①
現状での動作確認をしてみます。
まずは画面を起動して、画面遷移してみましょう。

ちゃんとフォームが表示されております!
続いて値を入力してsubmitボタンを押してみると・・・

表面上は何も起きてないように見えますが、ログを見てみるとフォームの内容がきちんと表示されてます!

IPC通信をやってみる
上記のプログラムにIPC通信を追加してみます。
今回は以下のような処理にします。
- 画面のレンダープロセスからメインプロセスにフォーム情報を渡す
- メインプロセスでメッセージを構築して、レンダープロセスに返す
- 画面にメッセージを表示する
ということで、まずはTest.vueに①の処理を追加します。
最初にipcRendererのimport文を追加します。
// Test.vue
<template>
...
</template>
<script>
import { ipcRenderer } from "electron"; // 追加
...
</script>
続いて同ファイルにonSubmitのメソッド内にipc通信処理を実装します。
今回はフォームのオブジェクトをtest-renderというイベント名で送信します。
// Test.vue
..
<script>
import { ipcRenderer } from "electron";
export default{
...
methods: {
onSubmit(event) {
event.preventDefault();
//console.log(this.form);
ipcRenderer.send('test-render', this.form); // 追加
},
onReset(event) {
event.preventDefault();
this.form.name = '';
this.form.age = '';
}
}
}
</script>
次は②のメインプロセス処理です。
メインプロセスはbackground.jsが担当しています。まずはipcMainのimport文を追加します。
// background.js
"use strict";
import { app, protocol, BrowserWindow } from "electron";
import { createProtocol } from "vue-cli-plugin-electron-builder/lib";
import installExtension, { VUEJS_DEVTOOLS } from "electron-devtools-installer";
import { ipcMain } from "electron"; // 追加
...
次はファイル末尾に通信の処理を実装していきます。
こちらはメッセージをtest-replyというイベント名でレンダープロセスに返します。
// background.js
...
// IPC通信処理
ipcMain.on('test-render', (event, form) => {
console.log(`データ受信:${form}`);
// メッセージをレンダープロセスに返す
event.reply('test-reply', `${form.name}は${form.age}歳です`);
})
最後に③の処理です。
再度Test.vueに戻り、スクリプトに以下を追記します。
// Test.vue
...
<script>
...
ipcRenderer.on('test-reply', (event, msg) => {
// メインプロセスから受信したメッセージをログに表示
console.log(msg);
})
</script>
動作確認②
それじゃあ動かしてみましょう!
フォームに入力してSubmitをクリックします。
(わかりやすいようにデバッグウィンドウを表示にしてます)

コンソールログにメインプロセスから送られたメッセージが表示されました!!
(実際には100才ではありません笑)

メインプロセス側のログ(VisualStudioCodeのログ)にも、ちゃんとレンダープロセスから受信した内容が表示されていますね(´▽`)

まとめ
今回はElectronの簡単な実装をやってみました。
プロセス間通信が多少クセがありますが、そこさえ乗り切ればvueとNode.jsの知識でアプリケーションを作ることができそうです(‘ω’)ノ
ちょっとしたアプリを作りたいときなどにお役に立ててもらえると嬉しいです(*´ω`*)
コメントを残す