2019年07月18日 18:04
住所を入力する際に、郵便番号を入れると町名まで自動で入力を補助してくれる機能を採用しているサイトは多くあります。
スクリプトを読み込んで、クラス名を input タグに付与するだけで簡単に使えるライブラリとして YubinBango があります。
サイトの README にもありますが、以下のように読み込むと使えるようになります。
<script src="https://yubinbango.github.io/yubinbango/yubinbango.js" charset="UTF-8"></script>
<form class="h-adr">
<span class="p-country-name" style="display:none;">Japan</span>
〒<input type="text" class="p-postal-code" size="8" maxlength="8"><br>
<input type="text" class="p-region p-locality p-street-address p-extended-address" /><br>
</form>
blade で書いていた時はこの方法でも良かったのですが、vue に変更した際に使えなくなってしまいました。
vue では input を v-model でバインドしているため、見かけ上自動入力されたように見えるだけで値が渡っていません。町名までしか自動入力はされないので、番地を書いた時に変数にも反映されるようになりますが、チラツキが気になったのでこの方法はやめました。
別の方法として YubinBango を実装しているコアを npm で読み込んで使うという方法があるのですが、こちらも不具合から使うことができません。
Vue.js にて郵便番号からの住所自動入力 - Qiita
本当なら npm install yubinbango-core から require などで読み込みたいのだがうまくいかず。誰か教えてください:pray_tone1:
YubinBango module が export されていない · Issue #4 · yubinbango/yubinbango-core
どうやら更新が 3 年前で止まっており、修正のためのリクエストも受け入れられていなかったので、YubinBango は使わないことにしました。
ライブラリを読み込むのではなく、Ajax を使って外部 API を使うことでも自動入力をすることができます。
axios を使っているので、実際に Vue で使おうとすると以下のようになります。
<template>
<form>
<input type="text" maxlength="8" v-model="form.zipcode"><br />
<input type="text" v-model="form.address" /><br />
</form>
</template>
<script>
export defalut {
data: {
form: {}
},
computed: {
zipcode() {
return this.form.zipcode;
}
}
watch: {
async postalCode(val) {
if (7 > val.length) {
return;
}
const res = await axios.get(`https://api.zipaddress.net/?zipcode=${val}`);
if (200 === res.data.code) {
this.$set(this.form, "address", res.data.data.fullAddress);
}
}
}
}
</script>
v-model="zipcode"
でバインドされている input
タグが入力を受けるたびに、watch
メソッドを使ってリクエストを行います。何度もリクエストするのは負荷がかかるので、日本で使われている郵便番号の桁数(7
桁)を超える入力であった時のみリクエストします。
この方法で問題ないと思ったのですが、JavaScript で外部 API を呼び出そうとすると CORS に引っかかってしまうようです。
そのため、外部 API にアクセスするのはサーバ側(今回は Laravel)で、Ajax はサーバ側の API を叩くことで取得が可能です。
Route::get('zipcode', function (Request $request) {
$url = "https://api.zipaddress.net/?zipcode={$request->zipcode}";
return file_get_contents($url);
});
- const res = await axios.get(`https://api.zipaddress.net/?zipcode=${val}`);
+ const res = await axios.get(`/api/zipcode/?zipcode=${val}`);
PHP - laravel + vue + axios で OpenWeatherMapAPI から天気を取得したい| teratail
file_get_contents を使うのはあまり良くないようなので、cURL で取得したほうが良さそうです。
p { margin-bottom: 1em; } blockquote p { margin-bottom: initial; } #content ul { padding-left: 40px; } .token.operator { background-color: initial; }