appendを使用した方法
vuetifyのv-text-tableを使う際、テキストボックス内の値を削除するために「clearable」を使用する場面が多いと思います。単に、値を消すだけであれば、clearableを設定すれば問題は無いですが、APIへ渡すパラメーターがnullになってしまったり、子画面まで紐づけて処理を行いたい場面に直面したので、その時の解決方法を書いていきます!
1. celearableの特徴
v-text-field
の削除機能として clearable
がありますが、使用した際の戻り値に注意を払う必要があります。
<div>
<v-text-field
class="sampleCSS"
v-model="sample"
clear-icon="mdi-close-circle"
clearable
/>
</div>
<script>
export default {
data: () => ({
sample: "",
}),
watch: {
sample() {
console.log(this.sample);
},
},
</script>
<style lang="scss" scoped>
.sampleCSS {
width: 10%;
margin-left: 2.5%;
}
</style>
上記の簡易的なコードを実装すると、シンプルなテキストフィールドが表示され、テキストを入力すると同様のデータの取得を確認出来ます。
次に、削除アイコンを押下すると、v-modelの変数と共に空ではなく「null」として初期化されてしまいます。
このように「null」として返されてしまうので、削除したから空文字列になると間違って認識してしまうケースも現れてくるので注意が必要です。(現に、自分は空文字で返却されると勘違いしていました。)
ちなみに、v-selectの場合は「undefind」となります。
今回は、値をnullではなく空文字としてサーバ側へ送る為、clearable以外のpropを用いて対応しました!
2. appendの付与
clickイベントへ append をバインドさせ、値の削除機能と同時に処理を加えることが可能となります。
1のsample.vueを修正し、下記propを加えます。
・append-icon
:削除ボタンアイコン
・@click:append
:クリック時の削除処理
<div>
<v-text-field
class="sampleCSS"
v-model="sample"
append-icon="mdi-close-circle"
@click:append="sample = ''"
/>
</div>
<script>
export default {
data: () => ({
sample: "",
}),
watch: {
sample() {
console.log(this.sample);
},
},
</script>
<style lang="scss" scoped>
.sampleCSS {
width: 10%;
margin-left: 2.5%;
}
</style>
これで、「削除アイコンを押下した際にテキストの中身を空にしてください。」と処理を走らせるので、先程clearableの時は「null」になってしまいましたが、空文字への変換が確認出来ました!
appendを使用する際の特徴としては、初期表示時の状態でも削除アイコンが表示してしまう点が挙げられます。値を入力した場合のみにアイコンを出現させたいのであれば、ボタンの表示制御が必要です。
こちらの記事は参考になりそうです!
空文字には出来たけど、子画面から値を受け取ってきた際に、親も子も空の状態にしたい!そんな場面がありましたので、第一引数を子画面側の処理、第二引数を親画面の処理とし、追記しました。
3. appendへ複数の処理を加える
ボタン押下時、子画面(ポップアップ)を表示し値を親画面へemitしてくるケースでは、下記のように対応しました。
@click:append="第一引数, (第二引数)"
・第一引数:子画面に反映する処理
・第二引数:親画面に反映する処理
//親画面
<template>
<div>
<v-text-field
class="sampleCSS"
v-model="sample"
append-icon="mdi-close-circle"
@click:append="append(), (popSample = '')"
/>
<v-btn class="btn" v-on:click="openDialog">
ボタン
</v-btn>
</div>
<div>
<v-dialog v-model="dialog" :max-width="500">
<Truck
:isOpenDetailDialog.sync="dialog"
@click="open"
:dataInfo="dataInfo"
/>
</v-dialog>
</div>
</template>
<script>
export default {
data: () => ({
sample: "",
popSample: "",
dataInfo: {
item: "",
},
dialog: false,
}),
methods: {
append() {
this.popSample = "";
},
open(value) {
this.dataInfo = value;
this.popSample = this.dataInfo.item;
this.dialog = false;
},
openDialog() {
this.dialog = true;
},
},
watch: {
sample() {
console.log(this.sample);
},
},
</script>
<style lang="scss" scoped>
.sampleCSS {
width: 10%;
margin-left: 2.5%;
}
.btn {
margin-left: 1.5%;
width: 5%;
background-color: #1976d2;
color: #ffffff;
}
</style>
子画面の、popSample
へ処理を渡したい際に、第一引数へ値を空にする処理をappend()
に記します(子画面でのコードは省略しています。同じようにv-text-fieldが存在し、ボタン押下する事で親仮面へ値がセットされると認識してもらえれば問題ないです。)。
今回は、親画面同様に値を空文字にしたい為、簡単なコードとなっていますが、API側の送り値を再度セットしたり、SCSSの動的設定なども出来るだろうと考えているので、試していこうかなと思っています。
おわりに
今までclearableを何気なく扱い、削除した際の値がnullになってしまう確認まで行ってはいなかったので、今後一つ一つのアクションで異なってくる点も調べていこうと思います...!clearableを使用し、APIへパラメータを送る際に同様の問題直面してしまった際にお役に立てればと記述しました!
参考
・Bug Report on Clearable:https://github.com/vuetifyjs/vuetify/issues/11474
・Feature Request on v-text-field:https://github.com/vuetifyjs/vuetify/issues/4144