Node.jsでメモアプリを作って遊ぶ(そのさん)


前回の時点でひとまずメモアプリっぽい何かは作れたんだけれども、jQueryでゴリゴリ書いてた部分をナウいライブラリ「Vue.js」に置き換えて遊んでみようと思う。

もともと俺がjQuery使い始めた理由ってのも、6~7年前ぐらいにモダンブラウザとレガシーブラウザが入り乱れた状況を打開するためだった気がする。まあ、IE6~8あたりのバグ対応でCSSハックせざるを得なかったけどな。今まで惰性で使い続けてきたのだけれども、今ではモダンブラウザで動けばOKな風潮だからなー。

そいで今どきのトレンドを軽く調べてみると、Googleさんが作ったAngularとか、Facebookさんが作ったReactとか色々あるのだけれど、jQueryを置き換えるのであればVue.jsが手っ取り早いという噂だ。まあ、WEB上の自信ニキ達がそう言っているだけであって俺は知らんのだが、全部触ると学習コストがパない感じになりそうなので、とりまVue.js触ってみまちゅか。

さっそくKindle Unlimited漁っていい感じの参考書をGETしたので、こいつを頼りに手を動かしてみる事にした。斜め読みした上での実装なので不安ではあるが、まず手を動かして糞みたいなコードでも作り上げる所がスタートラインだと思うんや。とりま動けば大正義(暴論)

Vue.jsとaxios.jsを読み込む

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>

いつもjQueryを使うときはCDN(エッジコンピューティングがうんぬんかんぬんでよく分からないけど近場のサーバからコンテンツ配信してくれるやつ)を使って読み込んでるのだが、Vue.jsも例に漏れずCDNに置いてあるっぽいのでURLコピペしてくる。んで、詳しくは後述するけれどもAjaxっぽい事をするためにaxiosとかいうライブラリもCDNから読んできておく。

メモを作ったり消したりするところを改造

<div id="create-memo">
    <ul>
        <li>
            <p class="caption">Title</p>
            <input v-model="memoname" type="text" name="memoname" id="">
        </li>
        <li>
            <p class="caption">Memo text</p>
            <textarea v-model="memotext" name="memotext" id="" cols="30" rows="10"></textarea>
        </li>
        <li>
            <input v-on:click="save_memo" type="button" id="memo_create" value="SAVE">
            <input v-on:click="delete_memo" type="button" id="memo_delete" value="DELETE">
        </li>
    </ul>
</div>

まず「index.ejs」に書いてたタグを、こんな感じに変えた。

inputだとかtextareaだとかのフォーム入力に指定してる「v-model」ってのが、「双方向データバインド」とかいう仕組みらしい。早い話が、「Javascriptからv-modelに指定した要素の値をいじれたり取得できるやでー」ということなのだろう。メモの名前(ファイル名)とメモの内容(テキスト)を取得したいので、それぞれに「memoname」「memotext」というv-modelを設定しておいた。

それで次は、どうやってSAVEだとかDELETEだとかのボタンのクリックイベントを発火させるんだぜという話なのだが、「v-on」とイベントを組み合わせると良いらしい。で、指定したJavascript側のメソッドを実行すると。なので、SAVEボタンを押したら「save_memo」、DELETEボタンを押したら「memo_delete」を走らせるように指定しといた。

あ、ちなみに今更だけど「v-某」ってのはディレクティブと呼ぶらしい。なんか意識高そうだし響きがかっこいい単語なので今後は積極的に使っていきたい。一瞬「え?探偵?」と思ったが、そっちは「ディテクティブ」だった。あかん、コナンの見すぎや。

// メモ書き込んだり削除したりするやつ
let create_memo = new Vue({
    el: "#create-memo",
    data : {    // フォームの初期値
        memoname : "",
        memotext : "",
    },
    methods : {
        save_memo : function(){
            axios.post("/", {"memoname": this.memoname, "memotext" : this.memotext}).then(function(response){
                // 書き込めたら再読込してリスト更新
                location.reload();
            });
        },
        delete_memo : function(){
            axios.post("/", {"isdelete": this.memoname}).then(function(response){
                // 削除できたら再読込してリスト更新
                location.reload();
            });
        }
    }
});

次に、スクリプト部分はこんな感じに変えた。jQueryで作ってたときは隠しフォーム作ってゴリゴリやってたけど、なんかめんどくせえので動的にPOSTする感じに。

「el」はVue.jsを適用する要素で、「data」はデータオブジェクト。今回は「#cteate-memo」以下にv-modelとして指定した「memoname」と「memotext」がそれにあたるのだろう。「methods」にさっきタグの方に書いたメソッド郡を定義してやる。

んで、Vue.jsでPOSTってどうやんのさ?と思って調べたのだが、どーも「axios」っていう別のライブラリと組み合わせるのがセオリーっぽい雰囲気なので、そいつを使ってやってみる。公式ドキュメントを見る限り、キーと値をセットにしたデータ配列を渡してやったり、then()に送ったあとのイベントを書けるっぽい。メモ一覧の表示更新をapp.js側でやってしまってるので、乱暴だけどページ再読込して再描画してる。まあいっか。

// req.body.某を配列として扱う
app.use(bodyParser.urlencoded({ extended: true }));
// ついでにリクエストをJSONで扱う
app.use(bodyParser.json());

POSTされたデータ受ける側の「app.js」はそんままで行けるかなーと思ってたのだが、どうもこいつはデータをJSONで送るっぽいので、bodyParserの設定を合わせておく事でうまく受け取ることができた。

メモを読み込むところを改造

<div id="list_memo">
    List of memo
    <ul>
    <% list_memo.forEach(function(item){ %>
        <li v-on:click="load_memo('<%= item %>')"><%= item %></li>
    <% }); %>
    </ul>
</div>

続けて、メモを読み込むところを改造した。index.ejsのタグ部分でEJSの繰り返し処理でファイルのリストを出力しているのだが、ここにも「v-on:click」でクリックイベントを設定してやる。で、呼び出すメソッドの引数にファイル名(item)をぶちこんでやった。

// メモ読み込むやつ
let list_item = new Vue({
    el: '#list_memo',
    methods : {
        load_memo : function(memoname){
            axios.get("memo/"+memoname).then(function(response){
                create_memo.memoname = memoname;
                create_memo.memotext = response.data;
            });
        }
    }
});

続いてスクリプト部分。ここでは、他のVueオブジェクトが持つモデルに対して変更を加えたかったので、さっき作ったVueオブジェクト(create_memo)のメンバに対して、GETしてきた結果を直接ぶちこんでいる。試しにやってみたらできちゃった感じなので、お作法的に良いのかは分からないが…まあ、動いたから良しとしよう。

Vue.jsを触ってみた感想

今回のメモアプリだと糞みたいな処理しかやってないのでアレだが、なんか思ったより苦労せずjQueryから移行できた印象。移行したあとのコードを眺めてみて思ったのだが、Vue.jsで組んだ場合はHTML部分をパッと見た時点で「あっ、こいつスクリプトから弄られる要素なんやな(察し)」といった感じになるので、コード全体の見通しが良くなった気がする。錯覚かもしんないけど。jQueryだったらどんな要素でも弄り放題なので、HTMLとJavascriptを行き来しながら確認する必要があったのだが、それが無くなるというのは割と大きいかもしんない。

いろんなサイト見てるとよく比較対象に挙げられてるReactとかAngularとかも手を出したいんだけどなー。なんか学習コスト高そうだし、今回みたいなNode.jsを勉強するついでじゃなくて、これはこれで腰据えてやってみたいのだぜ。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)