LoginSignup
14
15

More than 3 years have passed since last update.

VuetifyでTodoリストアプリに使えそうなコンポーネント

Last updated at Posted at 2020-05-06

背景

Vueで作ったシンプルなTodoリストをお洒落にするべく、Todoリストで使えそうなVuetifyのコンポーネントを下調べする。

作ったTodoアプリ

Before

vue-todo.gif

After

vuetify-todo.gif

ソース

デモ

チェックボックス

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にはcolumnrowという属性が用意されており、水平方向・垂直方向に並べ替えられる。デフォルトはcolumnで水平方向に並ぶ。
v-modelでバインドした変数には、選択したv-radiovalue属性に設定されている文字列が入る。


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-formv-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-menuv-dialogと組み合わせることで、v-text-fieldをへのフォーカス?をトリガーにv-date-pickerを起動させることが可能。
v-menuv-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-menuv-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>
14
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
15