【Vue.js】v-model以外でフォームデータ取得
需要があるかわかないが、メモ🖋🗒
モデルバインディング以外でも、(通常のjsの手法で)フォームデータ取得できるってよ
Vue.js使ってるんだから、v-modelでモデルバインディングした値を取得すれば良い、というのは百も承知なのですが、とりあえずメモしておきます。
テンプレート
ユーザ名とパスワードを入力させるログイン画面(ログインフォーム)を想定
<!-- テンプレート側 -->
<template>
<v-form>
<input type='text' placeholder='Your name' ref='input_name' v-model="user.username" /><br>
<input type='password' placeholder='Password' ref='input_password' v-model="user.password" /><br>
<!-- イベントオブジェクト自体を取得するときは @click="doSignIn($event) にしてあげる -->
<!-- パラメータとして渡したい引数がないなら()も省略化、Vue.jsのシュガーシンタックス(糖衣構文) -->
<v-btn type="submit" @click="doSignIn">Sign In</v-btn><br>
</v-form>
</template>
スクリプト
クリックイベント発生時にフォームデータを取得して、axiosで裏側(API)に送信する流れを想定
<script>
import axios from "axios"
export default {
data() {
return {
user: {}
};
},
methods: {
doSignIn:async function() {
// <form>ブロック内の各<input>をref属性値で指定することで、フォームの入力データを取得
let username = this.$refs.input_username.value // ref属性'input_username'のフォームの値
let password = this.$refs.input_password.value // ref属性'input_password'のフォームの値
this.getUserPage(username, password)
},
getUserPage:async function(username, password){
const formData = new FormData()
formData.append('username', username)
formData.append('password', password)
let accessToken = null
let axiosInstance = axios.create({
'headers': {'Content-Type': 'multipart/formdata'}
})
// axiosのget()とかの送信はまた別途記事を参照してください(下記の処理は今回の記事の内容とあんまり関係ないです)
await axiosInstance
.get("https://hogehoge/api.endpoint", formData, {withCredentials: true})
.then(response => {
accessToken = response.data
})
.catch(error => {
console.log(error);
})
return accessToken
},
参考ページでもベストプラクティスじゃねーよって怒られてますが・・・
まあ、遅延処理とかに使うのかな?
そんなタイミングがあるかは不明だけど、非リアクティブな値取得として、使えそうな気がする。あとなんとなく、こっちの手法の方が、イベント発生時にフォームデータから直接、値を取得している(完全に気のせいな)気がする。通常の<form>タグ内の<input>タグだけではなく、Vuetifyの<v-form>内のものでもこれで取得できるから安心感がある(のかな?)
js基礎知識すら元々しょぼいので、その辺りも含めて復習せねば。。。
根本的な理解が疎かなので、随時修正予定
変なところあったら、優しめにご指摘いただければ、感謝の極みです。
追記
注意事項
ref属性への参照refsは、コンポーネントの読み込み時に発生するみたい
正確には「$refs は、コンポーネントがレンダリングされた後にのみ生成」されるらしい(公式)
調査中だけど、その影響か、値取得と同時にコンポーネントが再読み込みされている気がする・・・