#はじめに
プログラミング学習をはじめ、10カ月です。
現在はLravelとVue.jsを学習しています。
この組み合わせだと世間的には、SPAと決まっているのですか?
Vueも少しずつわかってきたので、laravelのbladeをVueに書き替えて、MPAを作り始めました。
基本のCRUD処理をと思いましたが、さっそくつまずきました。
register画面を作ろう
laravelやVue.jsの基本は理解している前提で進めていきます。
ポイントを押さえながら解説します
まずは基本となるregister.phpです。
<!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">
<meta name="csrf-token" content="{{ csrf_token() }}"> //①
//中略(cssなど)
<title>title</title>
</head>
<body>
<div id="app">
<registerform-component
:old="{{ json_encode(Session::getOldInput()) }}" //②
:errors= "{{ $errors }}"> //③
</registerform-component>
</div>
<script src="{{ mix('js/app.js') }}"></script>
</body>
htmlではポイントは3つ
①laravelではcsrf対策を取らないといけません。
headにトークンを仕込んでおきます
②フォームで重要なのは入力ミスがあった場合、元のフォームにリダイレクトされます。入力した内容は残って欲しいですよね。
laravelのbladeでは、oldヘルパーが使えたのですが、Vueでは使えませんでした。
ここはあとで解説します。
③入力ミスがあった場合、何が間違っているのか、バリデーションによるエラーメッセージが表示されます。
laravelでは$errorsでどこからでも拾ってこれるそうですね。
$errors変数はwebミドルウェアグループに所属する、Illuminate\View\Middleware\ShareErrorsFromSessionミドルウェアによりビューに結合されます。このミドルウェアが適用される場合は、いつでもビューの中で$errors変数が使えます。$errors変数はいつでも定義済みであると想定でき、安心して使えます。
https://readouble.com/laravel/5.5/ja/validation.html
しかし、これもVueの中では素直に使えませんでした。
##Componentを作ろう
今回はRegisterForm.Vueを作成しました。
予め使えるようコンポーネントの登録はしておいてください。
<template>
<form action="/register" method="POST"> //④
<input type="hidden" name="_token" :value="csrf"> //⑤
<div class="form-group">
<label>名前</label>
<strong class="error" v-for="value in error.name">{{ value }}</strong> //⑥
<input class="form-control" name="name" type="text" v-model="name"> //⑦
</div>
<div class="form-group">
<label>Email</label>
<strong class="error" v-for="value in error.email">{{ value }}</strong>
<input class="form-control" name="email" type="text" v-model="email">
</div>
<div class="form-group">
<label>パスワード</label>
<strong class="error" v-for="value in error.password">{{ value }}</strong>
<input class="form-control" name="password" type="password" v-model="password" autocomplete="off">
</div>
<div class="form-group">
<label>再入力</label>
<input class="form-control" name="password_confirmation" type="password" v-model="password_confirmation" autocomplete="off">
</div>
<input type="submit" class="button" value="登録"> //⑧
</form>
</template>
<script> //⑨
export default {
props:[
'old',
'errors'
],
data:function(){
return{
csrf: document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
name: this.old.name,
email:this.old.email,
password:'',
password_confirmation:'',
error:{
name:this.errors.name,
email:this.errors.email,
password:this.errors.password,
}
}
},
}
コンポーネントはこんな感じにしました。
④register登録は/registerにPOSTします。
⑤laravelではPOSTデータにcsrfトークンを仕込まないと、弾かれてしまいます。
scriptタグで取得したトークンをもたせます。
csrf: document.querySelector('meta[name="csrf-token"]').getAttribute('content')
これは、このコンポーネントが入るregister.phpのheadに記述したものをとってきています。
⑥ここはエラー文ですね。後述します。
⑦はVueの基本の双方向バインディングですね。
Vーmodelでinputが変更されると、dataも変更されます。
⑧でサブミットされますね。
先述の
:old="{{ json_encode(Session::getOldInput()) }}" //②
:errors= "{{ $errors }}"> //③
</registerform-component>
の③で
コンポーネントに変数$errorsを渡します。
コンポーネント内ではpropで使用することができます。
同様に②で入力したデータはセッションに保存されています。
これをgetOldInput()で取得できます。
これをjson_encode()でjsonデータに直してコンポーネントに渡しています。
propで受け取ったデータは、thisで使用できます。
dataの初期値にthisで取得したデータを入れることで、入力したデータやエラーメッセージを表示させることができます。
##まとめ
こうして、無事にフォームができたのでした。
かなり時間かかりましたが、なんとかなりました。
コンポーネントは複雑化させていきますので、
次はvuexを導入します。