heimdalの技術ノート

IT全般、Linux、Windows、プログラミング開発など、何でもござれ

electronを使ってmithril.js 超入門 m.route編

はじめに

m.routeについて、何パターンか紹介する。

準備


以前の記事からサンプルを持ってきてもいいが、
場所を用意したので、ここからダウンロードした方が早い。
https://github.com/xheimdal/mithriljs-sample-code
hello-mithrilを使用すれば良い。

環境

electron:1.4.7
mithril:0.2.5
nodes:7.0.0

m.route

m.routeは、m.mountが複数コンポーネントが使えるようになったもの。
呼び方は、公式に合わせてルートではなくラウトと呼ぶことにする。
シングルホームページのように複数ページがあることを想定した作りの場合に使用する。
色々使い方はありそうだが、簡単なのをいくつか紹介する。

app.jsを変更する。

パターン1

'use strict';

//ページの遷移先を設定
const move = {
    home:      () => {m.route("/")},
    dashboard: () => {m.route("/dashboard")}
}

//Home
const Home = {
    //controller省略
    view: () => {
        return [
            m("div", "Home"),
            m("button", { onclick: move.dashboard }, "dashboardへ移動")
        ]
    }
};

const Dashboard = {
    //controller省略
    view: () => {
        return [
            m("div", "dashboard"),
            m("button", { onclick: move.home }, "homeへ移動")
        ]
    }
};

//初回起動をHomeに設定。他のページも設定。
m.route(document.getElementById("root"), "/", {
    "/": Home,
    "/dashboard": Dashboard,
});

このパターンはボタン押下による画面遷移サンプルになる。

ソースの説明だが、まず、es6を意識して書いてみた。
「use strict」をつけて文法を厳格化。
5行目付近の

    home:function() {
        m.route("/")
    },

をアロー関数化。

home:      () => {m.route("/")}

thisの使い方さえ気をつければ良い。

varを使わず、const化。
基本、全てconstで定義し、再代入する変数のみletを使用する。
よりスコープを意識することも出来るため、積極的に導入していく。

動きとしては、moveを使ってページ遷移をしている。

パターン2

'use strict';

const move = {
    home:      () => {m.route('/')},
    dashboard: () => {m.route('/dashboard')}
};

const myProf = function(){
    this.name = m.prop('');
    this.age  = m.prop('');
};

const Home = {
    vm: (function() {
        const vm = {};
        vm.init = function(){
            vm.prof = new myProf();
            vm.prof.name('');
            vm.prof.age('');
        }
        return vm
    })(),
    controller: function() {
        Home.vm.init();
    },
    view: () => {
        return [
            m('div', 'なんちゃって登録画面'),
            m('div', '名前と年齢を入力してください。'),
            m('p',
                m('input[placeholder="名前を入力してください"]', {
                    onkeyup: m.withAttr('value', Home.vm.prof.name),
                    value  : Home.vm.prof.name()
                })
            ),
            m('p',
                m('input[type="number"][placeholder="年齢を入力してください"]', {
                    onkeyup: m.withAttr('value', Home.vm.prof.age),
                    value  : Home.vm.prof.age()
                })
            ),
            m('button', { onclick: move.dashboard }, '登録')
        ]
    }
};

const Dashboard = {
    view: () => {
        return [
            m('div', '登録結果'),
            m('div', 'あなたのプロフィールは、以下ですね?'),
            m('div', '名前は' + Home.vm.prof.name()),
            m('div', '歳は' + Home.vm.prof.age()),
            m('button', { onclick: move.home }, '登録画面へ')
        ]
    }
};

//初回起動をHomeに設定。他のページも設定。
m.route(document.getElementById('root'), '/', {
    '/': Home,
    '/dashboard': Dashboard
});

パターン1に対して、入力ボックスを配置。
ページ遷移後に入力したデータを表示するようにした。
他のソースは、今までの例を見ていくとわかると思う。

パターン3

'use strict';

const move = {
    home: () => {
        m.route('/')
    },
    dashboard: () => {
        const name = Home.vm.prof.name();
        const age = Home.vm.prof.age();
        m.route('/dashboard/' + name + '/' + age)
    }
};

const myProf = function() {
    this.name = m.prop('');
    this.age = m.prop('');
};

const Home = {
    vm: (function() {
        const vm = {};
        vm.init = function() {
            vm.prof = new myProf();
            vm.prof.name('hemdal');
            vm.prof.age('100');
        }
        return vm
    })(),

    controller: function() {
        Home.vm.init();
    },

    view: () => {
        return [
            m('div', 'なんちゃって登録画面'),
            m('div', '名前と年齢を入力してください。'),
            m('p',
                m('input[placeholder="名前を入力してください"]', {
                    onkeyup: m.withAttr('value', Home.vm.prof.name),
                    value: Home.vm.prof.name()
                })
            ),
            m('p',
                m('input[type="number"][placeholder="年齢を入力してください"]', {
                    onkeyup: m.withAttr('value', Home.vm.prof.age),
                    value: Home.vm.prof.age()
                })
            ),
            m('button', {
                onclick: move.dashboard
            }, '登録')
        ]
    }
};

const Dashboard = {
    view: () => {
        return [
            m('div', '登録結果'),
            m('div', 'あなたのプロフィールは、以下ですね?'),
            m('div', '名前は' + m.route.param("name")),
            m('div', '歳は' + m.route.param("age")),
            m('button', {
                onclick: move.home
            }, '登録画面へ')
        ]
    }
};

//初回起動をHomeに設定。他のページも設定。
m.route(document.getElementById('root'), '/', {
    '/': Home,
    '/dashboard/:name/:age': Dashboard
});

m.routeには、urlにパラメータを渡すことができるので、それを使ってみた。
/:name/:ageをurlにつけることで、渡せるようになる。
パラメータは、m.route.param("パラメータ名")で取得できる。
このソースコードだと、そこまでパラメータで渡すメリットがないかもしれない。

最後に

複数ページは意外と簡単に出来た。
1ページ1コンポーネントを意識しながら作れば良い。
パターンを紹介したが、これが正解かはわからない。
mithril.js自体が緩い縛りなので、いくらでも作り方がある。
その緩さは、これといった正解がないため、慣れるまではデメリットと感じるかもしれない。
mithril自体はまだまだ面白いので、今後も紹介しようと思う。
次はもう少しelectron側との連携を考えてみる。