2019.9.9
Vueでカクテルデータベースをリファインする話#2【API】
最近はyoutubeに動画投稿するのにハマっている昨今ですが、
あれを収益化するのをメインストリームにするのはマズいということで、プログラムの方も書かなくてはいけません。
そりゃもちろん収益化できるのに越したことはないのですが、自分にそんなに自信があるわけではありません。
ただ、これから先リスクを抑えて楽しく生活するには、
ファンベースな考えが一番いいかなと思ってやっているわけです。あと純粋に楽しいですしね。
youtubeである程度酒の話ができるようになったら、カクテル作れる協力者を募ったり、脱サラして店を持つという僕の念願の夢(?)を叶えるためのリスクが低減するしね。そういう目論見です。動画投稿するだけならリスクゼロなんで、やらない手はない。
Ptutorはどうなったんですかね????
はあ~~~~~~
んですが、食っていくためにはもうちょっと安易な手を打たないとマズいし、僕自身も仕事を減らしたいのでプログラムを書かなくてはいけません。っていうわけで、放置気味だったVueの話ですね。
どう考えても金になるのに
今回やるのは
APIを叩いて、結果をjsonで受け取りビューに表示するっていうのをSPAでやる、という部分です。
画像でいうとこの部分ですね。現行のシステムと違うのは、VueによるSPAである利点を最大限に活かして、
テキストボックスに入力を開始した時点で検索を開始し、該当件数を取得するっていうのをやります。
検索自体はAPI叩いてコントローラー側で処理するので、そこは大丈夫なんですけどAPIとの連携は僕にとっては
(Ajaxでやったことはあるとは言え、Vueでは)初めてなので記事にしてメモしておこうかな、と。
いきなりやってもしょうがないので、まずはAPIで文字列を受け取って表示する、っていうのをやりましょうかね。
リファレンスは
このページなんかが概念を理解するのに良さそうです。
ということで、とりあえずAPIでデータのやり取りをするところまでは完成したので、コード垂れ流しです。
<template>
<div style="display: flex">
<form method="post" v-on:submit.prevent="onSubmit">
<input class="text_search_input" type="text" name="txt" v-model="inputted"
v-bind:class="{ active: isActive, 'text-danger': hasError }">
<button type="submit" class="btn btn-sm btn-default">
<span class="tb-visible none"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></span>
<span class="tb-hidden">{{ message }}</span></button>
</form>
</div>
</template>
<script>
export default {
name: "fromName",
data: function () {
return {
isActive: true,
hasError: false,
inputted:"",
message:"名前から検索"
}
},
watch: {
inputted: function (newData, oldData) {
if (newData==="") {
this.hasError=false;
this.message = '名前から検索';
return false;
}
//バリデーション
if (!newData.match(this.validation)) {
this.hasError=true;
this.message = 'Error';
return false;//バリデーションエラー
}
this.hasError=false;
this.message = '検索中...';
var result=this.debouncedGetResult(newData);
}
},
created:function() {
this.debouncedGetResult = _.debounce(this.getResult, 500)
//バリデーション定義
this.validation = "[a-zA-Z0-9-]"; // 英数字・ハイフン
this.validation += "|[\u3041-\u3093]"; // ひらがな
this.validation += "|[\u30A1-\u30F6]"; // カタカナ
this.validation += "|[・ー ]"; // 記号
this.validation += "|[\u4E00-\u9FFF]"; //漢字
this.validation = "^(" + this.validation +")+$";
//バリデーション定義.end
},
methods:{
getResult:function(data){
console.log(data);
//return;
//dataを用いて検索し、該当件数を返す(APIより)
axios.post('api/fromName', {
word: data
})
.then(function (response) {
console.log("success");
console.log(response);
})
.catch(function (error) {
console.log(error);
})
}
}
}
</script>
Vueファイル、つまり検索バーにかんしては今このような実装になってます。バリデーション定義が残念というかゴミなんですけど、そのうち別ファイルに切り分けてごまかそうかなあと思ってます。
ただ、ぶっちゃけただのセキュリティ問題なので、怪しい記号だけ記載したブラックリスト方式の方が良かったかも知れません。
PHP側ではそうなってるんですけどね。頭の悪い実装です。
Route::post('fromName','SearchController@fromName');
ルーティングに関しては、API側でこう定義したらいいだけです。
これで
api/fromNameにアクセスすると、ここに到達するということになります。web.phpの方でその他すべてのルーティングを吸っててもちゃんと到達してくれるので、判定はこっちが優先的に動くみたいです。
class SearchController extends Controller
{
public function fromName(SearchFromWord $request){
//名前から検索
return response()->json([
"key1"=>$request->all()
]);
}
}
コントローラーの記述はこんな感じです。とりあえず受け取ったリクエストをそのまま返しています。
axiosのほうでCSRFトークンは自動送信してくれてるっぽいので、特にトークンを含める必要はないそうです。
これで、javascriptの方のthenのほうにレスポンスが送られてくる、って感じです。
ちなみにこんな雑な書き方でもいいらしい。配列ならjsonに書き換えてくれるんだってよ。
とりあえずこれでデータのやりとりはできるようになったので、DB問い合わせの部分だけリファインして送れば、結果は取得できそうですね。がんばりましょ。