本文書ではvue.jsを使ったシングルアプリケーションの作成を行ったことがない入門者を対象に1つのファイル(index.html)のみでデータ作成/取得/更新/削除処理 (CRUD)が行えるシングルページアプリケーションの作成方法の説明をおこなっています。

vue.jsのほかモーダルウィンドウを実現するためにvue-js-modalライブラリを利用しています。

作成するアプリケーションの画面

本文書を使って作成する最終的なシングルページアプリケーションは下記となります。

【ユーザ一覧画面】

ユーザ3名分の情報が表示される初期画面

ユーザ一覧
ユーザ一覧

【モーダルウィンドウによるユーザ登録画面】

ユーザ登録画面をクリックするとモーダルウィンドウが表示

ユーザ登録画面
ユーザ登録画面

【モーダルウィンドウによるユーザ更新画面】

各ユーザ行にある更新ボタンを押すとモーダルウィンドウが表示

ユーザ更新画面
ユーザ更新画面

 【ユーザ削除後の画面】

ID4のユーザを登録後、削除ボタンをクリックすることでID2,3のユーザ情報を削除しています。

ID2,3を削除して4を追加
ID2,3を削除して4を追加
シングルアプリケーションといってもVue Routerを使ったページ遷移は行っていません。vue.jsだけでユーザ情報の取得から更新までの処理をページ遷移することなく1つのファイルで行っています。

初期画面の作成

データ作成/更新/削除の機能を追加する前にvue.jsとbootstrapを使って初期画面の作成を行います。通常は外部との連携を通してデータの取得を行いますが、今回は初期データを設定した状態から開始します。

bootstrapはページやテーブルの見栄えを整えるために使用しているので必須ではありません。見栄えを気にしないのであればbootstapを読み込まなくても問題ありません。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Single Page Application</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
</head>
<body>
    <div id="app">
        <div class="container mt-5">
            <div class="row">
                <div class="col-md-12">
                    <h1>{{ title }}</h1>
                    <table class="table">
                        <thead class="thead-dark">
                            <tr>
                                <th>ID</th>
                                <th>NAME</th>
                                <th>EMAIL</th>
                                <th>更新</th>
                                <th>削除</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr v-for="user in users" v-bind:key="user.id">
                                <td>{{ user.id }}</td>
                                <td>{{ user.name }}</td>
                                <td>{{ user.email }}</td>
                                <td><button class="btn btn-primary">更新</button></td>
                                <td><button class="btn btn-danger">削除</button></td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const vue = new Vue({
            el: "#app",
            data: {
                title: 'ユーザ一覧',
                users: [],
            },
            created(){
                this.users = [
                    {
                        id: 1,
                        name: 'Leanne Graham',
                        email: 'Sincere@april.biz'
                    },
                    {
                        id: 2,
                        name: 'Ervin Howell',
                        email: 'Shanna@melissa.tv'
                    },
                    {
                        id: 3,
                        name: 'Clementine Bauch',
                        email: 'Nathan@yesenia.net'
                    },
                ]
            }
        })
    </script>
</body>
</html>

コードの中身はデータプロパティusersにライフサイクルフックのcreatedで3名のユーザ情報を登録し、v-forディレクティブを使って3名のユーザ情報をテーブルの行に展開を行っているだけのシンプルなものです。

作成したindex.htmlファイルをブラウザで確認するとユーザ一覧画面が表示されます。

ユーザ一覧画面
ユーザ一覧画面

データ作成機能追加

最初にユーザ登録の機能を追加します。ユーザの登録はモーダルウィンドウで行えるようにvue-js-modalライブラリを使用します。

vue-js-modalライブラリの設定

vue-js-modalはcdnを利用して使います。vue.jsのcdnの下に追加します。


<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-js-modal@1.3.31/dist/index.min.js"></script>

vue-js-modalを使用するためにVue.useの設定を行います。new Vueの行の上に追加します。


Vue.use(window["vue-js-modal"].default);

const vue = new Vue({
	el: '#app',

モーダルウィンドウの設定

新たにユーザ登録ボタンを追加しボタンをクリックするとモーダルウィンドウが表示される設定を行います。

clickイベントはまだ設定していませんが、h1タグの下にユーザ登録ボタンを追加します。このボタンをクリックするとモーダルウィンドウが表示されます。クリックイベントにはshowModalを指定しています。


<button class="btn btn-primary my-2" @click="showModal">ユーザ登録</button>

次にモーダルウィンドウで表示させる内容のmodalタグを追加します。modalタグは、<div id=”app”></div>タグの内部に追加する必要があります。ここでは <div id=”app”> の閉じタグ</div>の前に追加しています。modalを識別するためにnameはuser-modalを指定しています。


<!-- モーダルウィンドウ用 -->
<modal name="user-modal">
    <h2>ユーザ登録</h2>
</modal>

モーダルウィンドウが表示させるためにクリックイベントで指定したshowModalメソッドを追加します。showの引数にはmodalタグで指定したnameのuser-modalを設定します。


methods: {
    showModal(){
        this.$modal.show('user-modal');
    },
},

モーダルウィンドウを表示させる設定は完了したので、ブラウザで動作確認を行います。ユーザ登録ボタンをクリックしてモーダルウィンドウが表示が確認してください。

モーダルウィンドウの表示確認
モーダルウィンドウの表示確認

モーダルウィンドウの外側をクリックするとモーダルウィンドウが閉じられることも確認してください。

表示されたモーダルウィンドウの外側をクリック
表示されたモーダルウィンドウの外側をクリック

ユーザ登録フォームの追加

追加したモーダルウィンドウ上でユーザの登録に必要なフォームを表示させます。

まず、Vueインスタンスにユーザ登録に必要なデータプロパティformを追加します。


data: {
    title: 'ユーザ一覧',
    form:{
        id:'',
        name:'',
        email:''
    },
    users: [],
},

modalタグの中身をh2タグの文字列から入力フォームに変更します。各input要素はv-modalを利用してデータバインディングを行っています。v-modalでバインディングするのは先程追加したデータプロパティのformの各プロパティです。


<!-- モーダルウィンドウ用 -->
<modal name="user-modal" :height="400">
    <div class="card">
        <div class="card-body">
            <div class="card-title">
                <h2>ユーザ登録</h2>
            </div>
            <div class="card-text">
                <div class="form-group">
                    <label for="id">ID</label>
                    <input type="text" class="form-control" id="id" placeholder="IDを入力してください" v-model="form.id">
                </div>
                <div class="form-group">
                    <label for="name">NAME</label>
                    <input type="text" class="form-control" id="name" placeholder="NAMEを入力してください" v-model="form.name">
                </div>
                <div class="form-group">
                    <label for="id">EMAIL</label>
                    <input type="email" class="form-control" id="email" placeholder="Emailを入力してください" v-model="form.email">
                </div>
                <button class="btn btn-primary">登録</button>
            </div>
        </div>
    </div>
</modal>

フォームを追加したので再度ユーザ登録ボタンをクリックするとモーダルウィンドウにはユーザ登録のためのフォームが表示されます。

ユーザ登録画面
ユーザ登録画面

登録ボタンが表示されていますが登録ボタンをクリックしても何も起こりません。次は登録ボタンを押したあとの処理を追加します。

ユーザ登録処理の追加

入力フォームの登録ボタンにクリックイベントを追加して、ユーザ登録を行うメソッドregisterUserを追加します。


<button class="btn btn-primary" @click="registerUser">登録</button>

VueインスタンスのmethodsにregisterUserメソッドを追加します。registerUserメソッドの中では、入力した値からuserオブジェクトを作成して、配列のpushメソッドを使って配列usersの一番後ろに作成したuserオブジェクトを追加します。追加が完了するとthis.$modal.hideで表示しているモーダルウィンドウを非表示にします。


registerUser(){
    const user = Object.assign({},this.form);
    this.users.push(user);
    this.$modal.hide('user-modal');
},

ブラウザを利用して、ユーザ登録を行います。登録ボタンを押した後に入力したユーザが追加されるか確認を行ってください。ID4のJohn Doeユーザを追加しています。

新規にユーザを登録
新規にユーザを登録

登録ボタンを押して登録したユーザ情報は自動でテーブルの最後に追加され、表示されます。ページのリロードは必要ありません。

入力した値のリセット

再度ユーザ登録ボタンを押すと先ほど入力した値がそのまま入力されたままの状態となります。

登録したユーザ情報が入力フォームに表示される
登録したユーザ情報が入力フォームに表示される

入力した値をリセットする処理resetFormメソッドを追加します。


methods: {
    showModal(){
        this.$modal.show('user-modal');
    },
    registerUser(){
        const user = Object.assign({},this.form);
        this.users.push(user);
        this.$modal.hide('user-modal');
        this.resetForm();
    },
    resetForm(){
        this.form.id = '';
        this.form.name = '';
        this.form.email = '';
    },
},

ユーザ登録後に再度ユーザ登録のモーダルウィンドウを開いても登録が終わった値は表示されません。

データ削除機能

ユーザ情報削除処理の追加

ユーザ情報を削除ボタンを使って1行ずつ削除する機能を追加します。削除ボタンにクリックイベントを追加し、deleteUserメソッドを設定します。


<td><button class="btn btn-danger" @click="deleteUser(user)">削除</button></td>

deleteUserの引数にはuserの情報を渡します。VueインスタンスのmethodsにdeleteUserメソッドを追加します。indexOfメソッドを使って削除を行ったユーザの配列の番号を取得し、spliceメソッドを使ってindex番目の要素1つを配列から削除しています。


deleteUser(user){
    const index = this.users.indexOf(user);
    this.users.splice(index, 1)
},
通常のアプリケーションではaxiosなどを利用してAPI経由で削除したユーザ情報の削除処理を行う必要があります。処理方法について後ほど説明を行います。

ブラウザを使って削除ボタンを押すとユーザ情報が削除できるか確認を行います。ID2, ID3の行にある削除ボタンをクリックしてユーザを削除します。

ID2, ID3のユーザ情報を削除
ID2, ID3のユーザ情報を削除
新規で登録したユーザも削除ボタンで削除することができます。削除後にページのリロードは必要ありません。

データ更新処理

ユーザ情報更新処理の追加

登録済みのユーザ情報を更新する機能を追加します。ユーザ登録と同様に更新ボタンをクリックするとモーダルウィンドウが表示され、その中の入力フォームでユーザ情報の更新を行います。

更新ボタンにクリックイベントを追加し、editUserメソッドを設定します。


<td><button class="btn btn-primary" @click="editUser(user)">更新</button></td>

editUserの引数にはuserの情報を渡します。VueインスタンスのmothodsにeditUserメソッドを追加します。editUserの中では、indexOfメソッドを使って更新を行うユーザの配列の番号を取得します。配列の番号は更新時に必要になるので、データプロパティeditIndexを追加します。


data: {
    title: 'ユーザ一覧',
    form:{
        id:'',
        name:'',
        email:''
    },
    users: [],
    editIndex: -1
},

追加するeditUserメソッドの中では更新を行いたいユーザ情報(引数から取得したuser)をデータプロパティthis.formに挿入し、ユーザ登録に利用したuser-modalをユーザ更新でも再利用するためにthis.$modal.show(‘user-modal’)を実行します。


editUser(user){
    this.editIndex = this.users.indexOf(user);
    this.form = Object.assign({}, user);
    this.$modal.show('user-modal');
},

更新ボタンをクリックするとモーダルウィンドウにはユーザ情報が入った状態で表示されますが、タイトルはユーザ登録、ボタンは登録ボタンになっているので変更が必要になります。

更新ボタンでモーダルウィンドウ表示
更新ボタンでモーダルウィンドウ表示

新たにデータプロパティcreateFlagとv-ifディレクティブを使ってモーダルウィンドウ内の登録と更新で表示される内容を切り替えます。createFlagの初期値はtrueに設定します。


data: {
    title: 'ユーザ一覧',
    form:{
        id:'',
        name:'',
        email:''
    },
    users: [],
    editIndex: -1,
    createFlag: true,
},

<h2 v-if="createFlag">ユーザ登録</h2>
<h2 v-else>ユーザ更新</h2>

<button class="btn btn-primary" @click="registerUser" v-if="createFlag">登録</button>
<button class="btn btn-primary" @click="updateUser" v-else>更新</button>

editUserメソッドの中でcreateFlagをfalseにします。


editUser(user){
    this.createFlag = false,
    this.editIndex = this.users.indexOf(user);
    this.form = Object.assign({}, user);
    this.$modal.show('user-modal');
},

更新ボタンを押すとタイトルがユーザ登録からユーザ更新、登録ボタンから更新ボタンになっていることを確認します。

ユーザ情報更新画面
ユーザ情報更新画面

しかし、更新ボタンを押した後にモーダルウィンドウの外側をクリックし、モーダルウィンドウを閉じたあとにユーザ登録ボタンを押すと更新のままになっており、先ほど更新ボタンを押したユーザ情報が表示されます。

ユーザ登録ボタンをクリックしたあとに実行されるshowModalメソッドでcreateFlagをtrueに設定し、フォームに表示されているユーザ情報をクリアできるようにresetFormメソッドを追加します。


showModal(){
    this.createFlag = true;
    this.resetForm();
    this.$modal.show('user-modal');
},

これで更新ユーザ情報が表示される問題は解消されます。

ユーザ情報の更新反映処理の設定

最後にモーダルウィンドウ上で行ったユーザ情報の更新を保存するためにVueインスタンスのmethodsにupdateUserメソッドを追加します。updateUserメソッドは更新ボタンを追加した時にクリックイベントで指定されているメソッドです。


updateUser(){
    Object.assign(this.users[this.editIndex], this.form);
    this.$modal.hide('user-modal');
}

this.editIndexはeditUserメソッド実行時に取得した配列の番号です。

IDは2のユーザの更新ボタンをクリックして、Nameを変更し、更新ボタンを押してください。

ID2のNAMEを変更
ID2のNAMEを変更

即座にユーザ一覧に表示されている情報が更新されていることを確認してください。

更新されたユーザ一覧
更新されたユーザ一覧

更新、追加、削除を行っても正常に処理が行えることを確認してください。

vue.jsを使って1つのファイル(index.html)でデータ作成/取得/更新/削除処理 (CRUD)が行えるシングルページアプリケーションを作成することができました。