背景
Vueで作ったシンプルなTodoリストをお洒落にするべく、Todoリストで使えそうなVuetifyのコンポーネントを下調べする。
作ったTodoアプリ
Before
After
ソース
デモ
チェックボックス
Todoの完了などに使えそう。
Selection control components — Vuetify.js
単体のチェックボックスの場合
Vueでチェックボックスを使う場合とだいたい一緒。
value属性をつけると、チェックした時にその値が入るので、booleanを扱う際は注意。
See the Pen v-checkbox-single by popy1017 (@popy1017) on CodePen.
(おまけ)複数のチェックボックスの場合
シンプルなタグ付けとかに使えそう。
こちらもVueで使う時とだいたい同じ。
v-modelで指定する変数は配列にする。選択したチェックボックスに指定されているvalueの値が配列に入る。
See the Pen v-checkbox-multiple by popy1017 (@popy1017) on CodePen.
チェックボックスのアイコンを変える
on-icon属性とoff-icon属性でアイコン名を指定することで、チェックボックスのアイコンを変えることができる。
color属性でon-iconで指定したアイコンの色を変えることができる。
See the Pen v-checkbox-icon by popy1017 (@popy1017) on CodePen.
チェックボックスのアイコンの大きさを変える
アイコンの大きさを変える属性がなかった?ので、v-iconかv-btnでクリックのたびに動的に表示するアイコンを変え擬似チェックボックスを作る。
基本的には、<v-icon>{{iconName}}</v-icon>
として、クリックがあったらiconName
を変える。
v-iconには数段階でアイコンの大きさを変える属性が用意されている。
See the Pen v-large-dynamic-icon by popy1017 (@popy1017) on CodePen.
その他の選択コンポーネント
スイッチ
単体で使う場合、複数で使いたい場合ともにv-checkboxと同じように使うことができる。
See the Pen v-switch by popy1017 (@popy1017) on CodePen.
ラジオボタン
ラジオボタンはチェックボックス、スイッチとは少し違いv-radio-group
コンポーネントで複数のv-radio
コンポーネントを囲う必要がある。また、v-radio-group
にはcolumn
、row
という属性が用意されており、水平方向・垂直方向に並べ替えられる。デフォルトはcolumn
で水平方向に並ぶ。
v-model
でバインドした変数には、選択したv-radio
のvalue
属性に設定されている文字列が入る。
See the Pen v-radio by popy1017 (@popy1017) on CodePen.
入力フォーム
Todoの新規作成や編集に必須。
Text field component — Vuetify.js
基本の入力フォーム
v-text-field
コンポーネントを用いる。ちなみに、.lazy修飾子は効かないので注意。
対処方法としては、v-model.lazy="hoge"
は:value="hoge" @change="v => hoge = v"
に置き換えられるのでそう書く。
See the Pen v-text-field.lazy by popy1017 (@popy1017) on CodePen.
様々なオプション
See the Pen v-text-field-options by popy1017 (@popy1017) on CodePen.
バリデーション
こちらの記事を参考にさせていただきました。
Vue & Vuetifyでバリデーション付きのフォームを作ってみる - Qiita
公式はこちら。Text field component — Vuetify.js
rules
属性に、関数の配列を指定すればOK。指定する関数は、booleanかstringを返す必要がある。
ただし、rules
属性を付与しただけでは見た目が変わるだけなので、ボタンを押した時にチェックして違反があったら実行させないとか、そもそもボタンを押せなくするとかは別にやる必要がある。
See the Pen v-text-field-validation by popy1017 (@popy1017) on CodePen.
ボタン押下時にバリデーションチェックする
ボタン押下時にバリデーションを行うためには、v-form
コンポーネントに用意された関数を利用する。
<v-form ref="form">
とすると、すべての入力をチェックしすべてが有効なものかを判定するthis.$refs.form.validate()
が使える。また、その他の関数としては、入力状態をリセットするthis.$refs.form.reset()
、バリデーションの状態のみをリセットするthis.$refs.form.resetValidation()
が利用できる。
See the Pen v-text-filed-validate-btn by popy1017 (@popy1017) on CodePen.
入力項目が正常になるまでボタンを非活性にする
v-form
にv-model="変数名"
で全体のバリデーションの状態(true or false)を保持することが可能。
ボタンの活性・非活性を動的に変えるためには、<v-btn :disable="変数名">
とすればOK。(変数がtrueのとき非活性になる。)
See the Pen v-text-field-btn-disable by popy1017 (@popy1017) on CodePen.
DatePicker & TimePicker
Todoの締切日を設定するのに必要。
Date picker component — Vuetify.js
Time picker component — Vuetify.js
DatePicker
v-date-picker
コンポーネントを使う。
基本的な使い方
日本語化はlocale="jp-ja"
でできるが、各日付に日
がついてしまって見栄えが悪い。
対処方法としては、day-format
属性で日付テーブルに表示されるdayの文字列の書式をカスタマイズする。
こちらの記事を参考にさせていただきました。
VuetifyのDate Pickerを日本語化したら"日"ってついてくる、やだキモい - nanisore oishisou
See the Pen v-date-picker-ja by popy1017 (@popy1017) on CodePen.
テキストフィールドに埋め込む
v-menu
やv-dialog
と組み合わせることで、v-text-field
をへのフォーカス?をトリガーにv-date-picker
を起動させることが可能。
v-menu
やv-dialog
についてはあまり深く理解してないが、以下のような構造になっていると理解。
<v-menu> or <v-dialog>
<template v-slot:activator="{ on }">
<!-- テキストフィールドとかボタンとか、トリガーとなる要素 -->
<v-text-field v-on="on"></v-text-field>
</template>
<!-- templateで囲った要素でイベントが発火したときに表示したい要素 -->
<v-date-picker></v-date-picker>
</v-menu> or </v-dialog>
See the Pen v-date-picker-in-text-field by popy1017 (@popy1017) on CodePen.
TimePicker
v-time-picker
を使う。 Time picker component — Vuetify.js
使い方はv-date-picker
とだいたい同じ。(な気がする)
12時間・24時間表記の設定は、format="ampm(or 24hr)"
でOK。(デフォルトは"ampm"
)
v-date-picker
と同様、v-menu
やv-dialog
と組み合わせてv-text-field
と統合することも可能。
See the Pen eYpywyB by popy1017 (@popy1017) on CodePen.
(おまけ)DateTimePicker
公式では用意されていないので、有志の方が公開してくれているものを使う。
darrenfang/vuetify-datetime-picker: DatetimePicker component for Vuetify.js.
上記にオンラインデモへのリンクもある。
Card
各Todoを1つ1つのカードとして表示したい場合に使える。(自前でcssでやってたので是非使いたい。)
See the Pen v-card-default by popy1017 (@popy1017) on CodePen.
gridレイアウト(v-row
, v-col
)と組み合わせることで、様々なレイアウトを実現可能。(極端に画面幅を狭めると若干レイアウトが崩れる。)
See the Pen v-card-grid-layout by popy1017 (@popy1017) on CodePen.
トランジション
Todoを削除したり、完了にして非表示にするときなど、おしゃれにリスト間を詰めるために使える。
Transitions — Vuetify.js
Vueだとtransition
コンポーネントで囲って、v-enter, v-enter-leave
とかのスタイルを定義していたところを、v-fade-transition
とかv-expand-transition
とかで囲むだけで既存のトランジションが使える。(自分でスタイル定義して、transition
で使うこともできる。)
transition-group
の代わりに、group
属性をつけることでグループ化される。
CodePen上だとうまくうごかなかったのでコードを掲載。
<template>
<v-app>
<v-container>
<v-btn @click="insertNumber">+Insert</v-btn>
<v-fade-transition group leave-absolute hide-on-leave>
<v-card v-for="(n,index) in numbers" :key="n">
<v-row align="center">
<v-col>
<v-card-title>{{n}}</v-card-title>
</v-col>
<v-col cols="2">
<v-btn @click="removeNumber(index)" icon>
<v-icon>mdi-trash-can-outline</v-icon>
</v-btn>
</v-col>
</v-row>
</v-card>
</v-fade-transition>
</v-container>
</v-app>
</template>
<script>
export default {
name: "App",
data() {
return {
numbers: [1, 2, 3],
currentNumber: 4
};
},
methods: {
insertNumber() {
const id = Math.floor(Math.random() * this.numbers.length);
this.numbers.splice(id, 0, this.currentNumber);
this.currentNumber += 1;
},
removeNumber(id) {
this.numbers.splice(id, 1);
}
}
};
</script>