カクカクしかじか

技術的なアレコレ

Vue.jsでformタグ内の@clickイベントから画面ロードなしでDOMを更新出来ない問題の解決法

問題の概要

Vue.jsの@clickイベントでサーバーサイドにPOSTして、正常に完了した場合に画面をロードせずに一部のDOMを更新して送信完了表示したい。
しかし、画面が送信前の画面に戻ってしまってDOM更新後の画面にならない!?
サーバーサイドはステータス200で返っている....なぜ???

問題があったコードのフォーム部分の抜粋

<div v-if="とあるcomputedの条件">
  <form name="email_form">
    <中略>
    <button
       type="submit"
       class="btn btn_send_long"
       @click="submit"
       >送信する</button>
  </form>
</div>

今回やりたいことの流れ

Vue → Rails → 結果を表示

結論

<form> が悪さしてるっぽいです...

解説

<form> タグの中で@clickを呼ぶ場合にデフォルトで画面をリロードするイベントが発火するっぽいです。
画面の更新だけ行いたい場合は@clickを含む <button><form> ではなく <div> で囲ってあげれば大丈夫になります。

修正後

<form><div> に変更しました。

<div v-if="とあるcomputedの条件">
  <div name="email_form">
    <中略>
    <button
       type="submit"
       class="btn btn_send_long"
       @click="submit"
       >送信する</button>
  </div>
</div>

どうしてもformを使いたいけど画面ロードはしたくない場合

Vue.jsの公式ドキュメント にもある通り、 submit.prevent でリクエストを投げるようにすればページのリロードが走らないみたいです。

<!-- submit イベントによってページがリロードされません -->
<form v-on:submit.prevent="onSubmit"></form>

最後に

この問題で数時間溶かしてもうた...
同じ悲しみが生まれないように投稿させて頂いた次第ですw
公式ドキュメントはちゃんと読もう...ホンマに。。。

追記

こちらのやりとりに今回の答えが...