Vueなら複数ページの入力もたった1ファイルで開発できる!

さてさて、ここのところVueの話題から遠ざかってしまったので、また戻ってVueの魅力と「いかに楽できるか」を紹介していきたいと考えています。

この「いかに楽できるか」ということに考えがいったのは、私が開発業務をはじめた頃のことを思い出したからです。

当時は、フレームワークと呼ばれるものは主流ではなく全て自分でコードを書いていました。特に3キャリア全てに個別対応しないといけなかったモバイル向け開発は地獄でした(笑)

それが今では、LaraveVueなどのフレームワークが登場したおかげで開発で「・・・😫」となることは少なくなりました。

そして、その中の最たる例が「複数ページに渡る入力」だと考えています。

例えば、ショッピングサイトのamzonでもそうですが何か商品をカートに入れて、いざ注文をする時は入力が1ページで終わらず、数ページの入力が必要になってきますよね。

もしこれをPHPだけで実装するなら大変です。なぜなら各ページの入力をセッションなどに持たせて注文が終了するまで全データを保持しておかないといけないからです。(しかも、ページ移動は「次」だけでなく「前に戻る」も必要になってきます)

そこで!

今回はこういった複数ページに渡る入力を「Vueならたった1ファイルで実装できますよ」というのを知ってもらいたくて記事をお届けすることにしました。

ぜひ皆さんのお役に立てると嬉しいです😊✨

開発環境: Vue 2.6

やりたいこと

今回Vueで開発する内容は以下のとおりです。

  • 入力ページは「お客様情報」「配送情報」「クーポン情報」の3ページ
  • 各ページは「次へ」「戻る」ボタンで表示/非表示を切り替える
  • 入力フォームの上には「今が何の入力か??」が分かるようにナビゲーションを表示する
  • Vueを使って1ファイルだけで実装する

では、順を追って開発をしていきましょう!

基本のテンプレートをつくる

まずはじめに表示/非表示は無視して入力に必要なコンテンツをHTMLで作成します。また、後で必要になるVueの基本形も追加しておきます。

<html>
<head>
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div id="app" class="container pt-5">
        <div class="row">

            <div class="col-md-4 offset-md-4">
                <h1>&#x1F60A; お客様情報</h1>
                <div class="form-group">
                    <label>名前:</label>
                    <input class="form-control" type="text">
                </div>
                <div class="form-group">
                    <label>かな:</label>
                    <input class="form-control" type="text">
                </div>
                などなど
            </div>
            <div class="col-md-4 offset-md-4">
                <h1>&#x1F4E6; 配送情報</h1>
                <div class="form-group">
                    <label>住所:</label>
                    <input class="form-control" type="text">
                </div>
                配達時間:
                <div class="form-group">
                    <select class="form-control">
                        <option value="1">9:00〜12:00</option>
                        <option value="2">12:00〜15:00</option>
                        <option value="3">15:00〜19:00</option>
                        <option value="4">19:00〜21:00</option>
                    </select>
                </div>
                などなど
            </div>
            <div class="col-md-4 offset-md-4">
                <h1>&#x1F516; クーポン情報</h1>
                <div class="form-group">
                    <label>クーポンコード:</label>
                    <input class="form-control" type="text">
                </div>
            </div>
        </div>

    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
    <script>

        new Vue({
            el: '#app',
            data: {
                page: 1 // 入力ページ番号(1〜3)
            }
        });

    </script>
</body>
</html>

内容としては、「お客様情報」「配送情報」「クーポン情報」の3ブロックがあって、後ほどVueを使ってこの部分の表示/非表示を切り替えることになります。

また、Vueの中に用意した変数pageは現在のページ番号が入ってくることになり、表示はこの数字によって切り替わることになります。

ページ番号は次のとおりです。

  1. お客様情報 ・・・ 初期入力
  2. 配送情報
  3. クーポン情報

なお、今の状態でこのコードを実行するとこのようになります。

ページ番号によって入力を切り替える

では次に、先ほどの3ブロックの表示/非表示ができるようにしていきましょう。

・・・といってもここはとても簡単で、Vueが用意しているv-ifを追加するだけでOKです。

<div class="col-md-4 offset-md-4" v-if="page==1">
    <h1>&#x1F60A; お客様情報</h1>
    <!-- 省略 -->
</div>
<div class="col-md-4 offset-md-4" v-if="page==2">
    <h1>&#x1F4E6; 配送情報</h1>
    <!-- 省略 -->
</div>
<div class="col-md-4 offset-md-4" v-if="page==3">
    <h1>&#x1F516; クーポン情報</h1>
    <!-- 省略 -->
</div>

どうでしょう。

こうするだけでページ番号が変われば自動で表示が切り替わることになります。Vueの開発ってすごく楽です😊✨

入力内容とVueを連動させる

では、ここで<input>などの入力ボックスとVueを連動させておきましょう。

まずVue本体の方に変数paramsを用意します。
この中にそれぞれ、入力データが格納されることになります。

new Vue({
    el: '#app',
    data: {
        page: 1,
        params: {
            name: '',
            name_kana: '',
            address: '',
            delivery_time: '',
            coupon_code: ''
        }
    }
});

では、HTML側です。
Vueと変数を連動させるにはv-modelを使います。

<div class="col-md-4 offset-md-4" v-if="page==1">
    <h1>&#x1F60A; お客様情報</h1>
    <div class="form-group">
        <label>名前:</label>
        <input class="form-control" type="text" v-model="params.name">
    </div>
    <div class="form-group">
        <label>かな:</label>
        <input class="form-control" type="text" v-model="params.name_kana">
    </div>
    などなど
</div>
<div class="col-md-4 offset-md-4" v-if="page==2">
    <h1>&#x1F4E6; 配送情報</h1>
    <div class="form-group">
        <label>住所:</label>
        <input class="form-control" type="text" v-model="params.address">
    </div>
    配達時間:
    <div class="form-group">
        <select class="form-control" v-model="params.delivery_time">
            <option value="1">9:00〜12:00</option>
            <option value="2">12:00〜15:00</option>
            <option value="3">15:00〜19:00</option>
            <option value="4">19:00〜21:00</option>
        </select>
    </div>
    などなど
</div>
<div class="col-md-4 offset-md-4" v-if="page==3">
    <h1>&#x1F516; クーポン情報</h1>
    <div class="form-group">
        <label>クーポンコード:</label>
        <input class="form-control" type="text" v-model="params.coupon_code">
    </div>
</div>

なお、階層が深い変数にアクセスするには.(ドット)でつなぎます。

これで、入力に変更があったら、リアルタイムでVue内の変数が書き換えられますし、プログラムでその変数を変更されたら、今度は逆に入力ボックスの値が自動的に変更になり同期してくれることになります。

ページ移動のボタンをつくる

今のままでは入力ページを移動する方法がないので、「次へ」「戻る」ボタンをつくっていきます。

まずはHTMLです。

<div id="app" class="container pt-5">

    <!-- 省略(先ほどの入力ブロック) -->

    <div class="row">
        <div class="col-md-4 offset-md-4 pt-5">
            <button
                class="btn btn-secondary float-right"
                type="button"
                v-if="page<3"
                @click="next">次へ</button>
            <button
                class="btn btn-primary float-right"
                type="button"
                v-if="page==3"
                @click="submit">送信する</button>
            <button
                class="btn btn-secondary"
                type="button"
                v-if="page>1"
                @click="prev">戻る</button>
        </div>
    </div>
</div>

ここで重要なのは2点です。

1つ目はボタンについているv-ifの部分。
これも先ほどの入力ブロックと同じように「今が何ページ目か??」で表示する/しないが切り替わります。

具体的には次のとおりです。

  • ページ番号が「3」未満 ・・・ 「次へ」ボタンを表示する
  • ページ番号が「3」 ・・・ 「送信する」ボタンを表示する
  • ページ番号が「1」超 ・・・ 「戻る」ボタンを表示する

そして、もう一つは各ボタンにつけられたクリックイベント@click="***"の部分です。

これらのメソッドは以下のように追加しておいてください。

new Vue({

    // 省略

    methods: {
        next() {

            this.page++;

        },
        prev() {

            this.page--;

        },
        submit() {

            /* ここでAjax送信 */

        }
});

先ほども説明したように、Vueでは変数の中身が変更になった時点で自動的に表示/非表示が切り替わるので、たったこれだけのコードでOKです。

なお、もしaxiosAjax送信する場合は以下のようにしてください。

submit() {

    const url = '******';
    axios.post(url, this.params)
        .then((response) => {

            // ここで何かをする

        });

},

この時点でボタンをクリックすると入力ブロックの切り替えをすることができるようになっているはずです。

ナビゲーションをつくる

この部分は直接入力には関係ありませんが、ユーザビリティの観点からおまけ的に追加します。

amazonなどでもあると思いますが、「今どんな入力をしていて、あと何ページあるか」がひと目でわかる機能です。

実際の表示はこうなります。

(1ページ目)

(2ページ目)

(3ページ目)

では、まずはHTML側です。

<div id="app" class="container pt-5">
    <div class="row">
        <div class="col-md-6 offset-md-3 mb-5">
            <div class="row">
                <div :class="navigationCss(1)">&#x1F60A; お客様情報</div>
                <div :class="navigationCss(2)">&#x1F4E6; 配送情報</div>
                <div :class="navigationCss(3)">&#x1F516; クーポン情報</div>
            </div>
        </div>

        <!-- 省略(入力ブロック) -->

    </div>
    <div class="row">
        <div class="col-md-4 offset-md-4 pt-5">

            <!-- 移動ボタン -->

        </div>
    </div>
</div>

ここでもこれまでのやり方と同じくページ番号によって表示を切り替えるのですが、今回はv-ifは使わず、適用するclassの内容をnavigationCss()メソッドで切り替えます。

メソッドの中身はこうなります。

new Vue({

    // 省略

    methods: {

        // 省略

        navigationCss(targetPage) {

            if(this.page === targetPage) {  // 現在ページの場合

                return ['col-4', 'text-center', 'text-white', 'bg-info', 'p-2'];

            }

            return ['col-4', 'text-center', 'text-secondary', 'p-2'];

        }
    }
});

ここでは、「このメソッドにつけられたページ番号と実際の今のページ番号が同じかどうか??」をチェックして利用するクラス名を切り替えています。

つまり、今が1ページ目なら「お客様情報」の部分は背景にbg-infoが適用されて青くなり、text-whiteでテキストの色は白になります。逆にそれ以外の場合はテキストの色がtext-secondaryによって少し薄い色になります。

※ なお、コードが複雑になるので見送りましたが、このナビゲーションをクリックしたら各ページに移動できるようにすればもっと便利だと思います。

お疲れ様でした😊✨

テストしてみる

では、これでコードの説明は終了です。
開発したものをテストしてみましょう!

うまく行きました!😊✨

ダウンロードする

今回実際に開発したソースコードを以下からダウンロードすることができます。(CDNを使っているので展開したらすぐ実行できますよ!)

Vueで複数ページの入力フォームを実装

おわりに

ということで、今回は「Vueがいかに楽できるかを知ってもらいたい!」というテーマの下で複数ページの入力フォームをつくってみました。

ただ、その気持ちがちょっと強すぎて「Vueの回し者」みたいになってしまったかもしれません😂(当然ですが、ステマではありません)

・・・それにしても、話は戻りますが近年の開発はホントに楽になりましたね。

確かに、npmだったりビルドだったり新技術がたくさん出てくるので勉強は常に続けておかないとガラパゴス化するのは間違いないですが、その中から自分にあったもの、効率化できるものを選り分ければもっともっと楽で、なおかつ高品質なコンテンツ開発ができると思います。

ぜひ皆さんもご自身の開発に役立ててみてくださいね。

ではでは〜!

この記事が役立ちましたらシェアお願いします😊✨