34
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

VueAdvent Calendar 2022

Day 14

Vuetify3 でよく使うコンポーネントのメモ(1)

Last updated at Posted at 2022-08-25

このページは下記リンク先へ移行中です。

以下の記事は内容が古い可能性があります。新しい情報については上記記事を参照してください。

内容

よく使うかどうかは、主観に依存しています。この記事では主に form 関連のコンポーネントについて記述します。

Vuetify 3.3.6 の使用を前提にしています。動作が異なる場合や、ワーニング等が出るときは package.json のバージョンを確認してください。

詳細については、Vuetify3 の公式ページを参照してください。

関連記事

ヘッダ、バー、フッタ

画面構成の基本パーツとして、v-system-bar, v-app-bar, v-navigation-drawer, v-main, v-footer, v-button-navigation があります。

image.png

コード:

App.vue
<template>
  <v-app>
    <v-system-bar color="secondary">
      System Bar
    </v-system-bar>

    <v-app-bar color="primary">
      <v-app-bar-title>
        Application Bar
      </v-app-bar-title>
    </v-app-bar>

    <v-navigation-drawer permanent>
      Navigation Drawer
    </v-navigation-drawer>

    <v-main>
      <v-container>
        Main Contents
      </v-container>
    </v-main>

    <v-bottom-navigation>
      Button Navigation
    </v-bottom-navigation>

    <v-footer color="primary" app>
      Footer
    </v-footer>

  </v-app>
</template>

上記を参照してください。

ユーザが操作するパーツ

ボタン:v-btn

基本

マウスでクリックできるボタンです。クリックしたときのアクションは @click で指定できます。ボタンのキャプションは、英字を含む場合はすべて大文字に変換されます。

Vuetify2 のときは v-btnblock 要素だったのが、Vuetify3 stable では inline 要素になったようです。そのため、ボタンを複数並べると、デフォルトでは横に並ぶようになりました。

vuetify3.gif

コード:

App.vue
<template>
  <v-btn @click="submit">
    Submit
  </v-btn>
  <v-btn @click="cancel">
    Cancel
  </v-btn>
  {{ message }}
</template>
<script>
export default {
  data: () => ({
    message: ""
  }),
  methods: {
    submit(){
      this.message = "submit";
    },
    cancel(){
      this.message = "cancel";
    }
  }
}
</script>

@click で指定する関数には、引数も渡せます。

App.vue
<template>
  <v-btn @click="clickButton('submit')">
    Submit
  </v-btn>
  <v-btn @click="clickButton('cancel')">
    Cancel
  </v-btn>
  {{ message }}
</template>
<script>
export default {
  data: () => ({
    message: ""
  }),
  methods: {
    clickButton(arg){
      this.message = arg;
    }
  }
}
</script>

アプリの動作は、上のコードと全く同じになります。

スタイル(variant)、色、アイコン

variant を使うと、ボタンのスタイルを指定できます。

image.png

コード:

App.vue
<template>

  <div class="d-flex justify-space-between ma-2 pa-2">
    <v-btn color="primary">default</v-btn>
    <v-btn color="primary" variant="outlined">アウトライン</v-btn>
    <v-btn color="primary" variant="text">テキスト</v-btn>
    <v-btn color="primary" variant="flat">flat</v-btn>
    <v-btn color="primary" icon="mdi-home"></v-btn>
  </div>

  <div class="d-flex justify-space-between bg-black ma-2 pa-2">
    <v-btn>default</v-btn>
    <v-btn variant="outlined">アウトライン</v-btn>
    <v-btn variant="text">テキスト</v-btn>
    <v-btn variant="flat">flat</v-btn>
    <v-btn icon="mdi-home"></v-btn>
  </div>

  <div class="d-flex justify-space-between bg-black ma-2 pa-2">
    <v-btn color="black">default</v-btn>
    <v-btn color="black" variant="outlined">アウトライン</v-btn>
    <v-btn color="black" variant="text">テキスト</v-btn>
    <v-btn color="black" variant="flat">flat</v-btn>
    <v-btn color="black" icon="mdi-home"></v-btn>
  </div>

</template>

色は color 属性で指定します。class で指定すると、スタイルの整合性が崩れることがあります。スタイルは variant で指定します。outlined, flat, text あたりをよく使います。

color の反映のされかたは、variant によって違います。ボタンの親要素の背景色も、ボタンの配色に影響します。

アイコンは icon 属性で指定します。公式のドキュメントでは、icon が指定されているときは、下記のように InnerText があってもテキストが表示されないみたいな掻き方になってますが、実際にはテキストが優先されて表示されます。icon 属性を指定するときは、InnerText は空にします。

.vue
<v-btn icon="mdi-home"> Home </v-btn>

なお icon 属性を指定すると、自動的にボタンは丸くなります。丸くしたくない場合は、下記のようにします。

image.png

コード:

App.vue
<template>
  <div class="ma-10">
    <v-btn color="black">
      <v-icon>
        mdi-home
      </v-icon>
    </v-btn>
  </div>
</template>

ロード中、無効化

ロード中みたいなボタンも作れます。ボタンの無効化は disabled です。

vuetify3_2.gif

コード:

App.vue
<template>
  <v-btn @click="load" :loading="flag" class="ma-2">
    Load
  </v-btn>
  <v-btn @click="cancel" :disabled="!flag" class="ma-2">
    Cancel
  </v-btn>

</template>
<script>
export default {
  data: () => ({
    flag: false
  }),
  methods: {
    load(){
      this.flag = true;
    },
    cancel()
    {
      this.flag = false;
    }
  }
}
</script>

ボタンをロード中表示にすると、自動的に無効化されます。

別のページに飛ぶボタン

飛ぶ先の URL の指定は href 属性を使います。href 属性を使わずに a 要素を含めた場合、テキストの色はアンカーの色指定に準じるようです。vue-router を使用している場合に、サイト内の別のパスに飛ばすには to を使います。

image.png

コード:

App.vue
<template>
  <v-btn class="ma-2">
    <a href="https://next.vuetifyjs.com/en/components/buttons/">
      Vuetify3 Button
    </a>
  </v-btn>

  <v-btn class="ma-2"
    href="https://next.vuetifyjs.com/en/components/buttons/">
    Vuetify3 Button
  </v-btn>

  <v-btn class="ma-2"
    to="/about">
    /about
  </v-btn>
</template>

なお、href, to を使うと、何故か block を指定したときのように、ボタンの横幅が画面いっぱいになります。その場合でも max-width を使うか、幅が指定されている親要素に入れることで、横幅の制限はできます。

その他

他にも、ボタンの角を丸めたり、サイズを指定することもできます。詳しくは下記をどうぞ。

テキスト入力:v-text-field

キーボードとかを使って。テキストを入力することのできるコンポーネントです。

基本

v-model で入力した文字列を取得できます。

textinput2.gif

コード:

App.vue
<template>

  <v-container>
  <v-text-field v-model="message">
  </v-text-field>
  {{ message }}
  </v-container>

</template>
<script>
export default {
  data: () => ({
    message: ""
  }),
}
</script>

入力後に Enter キーを押したら何かする

v-form をつかって、昔ながらの書き方をする必要があるようです(多分)。他の方法あるんでしょうか。ページのリロードを防ぐためには、preventDefault を書く代わりに <v-form @submit.prevent=""> とします。

textinput3.gif

コード:

App.vue
<template>
  <v-container>
    <v-form action="#" @submit.prevent="pushEnter">
      <v-text-field v-model="inputText">
      </v-text-field>
    </v-form>
    {{ message }}
  </v-container>

</template>
<script>
export default {
  data: () => ({
    message: "",
    inputText: ""
  }),
  methods:{
    pushEnter()
    {
      this.message = this.inputText;
      this.inputText = "";
    }
  }
}
</script>

いろいろなスタイル

テキストを入力する前の状態:

image.png

テキストを入力した後の状態:

textinput1.gif

コード:

App.vue
<template>
  <v-container class="pa-2" >
    <v-text-field
    ></v-text-field>

    <v-text-field
        label="デフォルトのスタイル"
        placeholder="「ここに何か入力しろ」とか書ける"
    ></v-text-field>

    <v-text-field
        label="下線だけのシンプルスタイル"
        variant="underlined"
        placeholder="clearableを付けると、右にXボタンが出るようになる。"
        clearable
    ></v-text-field>

    <v-text-field
        label="枠囲みのスタイル"
        variant="outlined"
        placeholder="counterを付けると文字数を表示する(あくまで数えるだけ)"
        counter="20"
    ></v-text-field>

    <v-text-field
        label="コンパクトサイズ"
        hide-details="auto"
        placeholder="詳細表示のスペースがなくなって、縦幅が小さくなる。"
    ></v-text-field>
    <v-text-field
        label="デフォルト"
        placeholder="デフォルトだと下に少しスペースがあいている。"
    ></v-text-field>

    <v-sheet width="50%">
    <v-text-field
        label="サイズ制限"
        placeholder="幅が指定された親要素に入れて制限するか、v-col などを使う。"
    ></v-text-field>
    </v-sheet>
  </v-container>
</template>

横幅は、親要素いっぱいに広がります。横幅を制限したいときは、親要素の幅を指定します。

色の指定

基本的に、自由に指定できません。テキストや下線などの色は、v-text-field 指定しても反映されません。親要素の色から、自動的に、v-text-field の配色が決まるようです。

image.png

コード:

App.vue
<template>
  <v-container>

    <v-container class="d-flex flex-row"> 
      <v-sheet class="bg-black ma-2" width="50%">
        <v-text-field
          label="背景が black の場合"
        ></v-text-field>
      </v-sheet>
      <v-sheet class="bg-grey ma-2" width="50%">
        <v-text-field
          label="背景が gray の場合"
        ></v-text-field>
      </v-sheet>
    </v-container>

    <v-container class="d-flex flex-row"> 
      <v-sheet class="bg-red ma-2" width="50%">
        <v-text-field
          label="背景が red の場合"
        ></v-text-field>
      </v-sheet>
      <v-sheet class="bg-blue ma-2" width="50%">
        <v-text-field
          label="背景が blue の場合"
        ></v-text-field>
      </v-sheet>
    </v-container>

    <v-container class="d-flex flex-row"> 
      <v-sheet class="bg-red-darken-4 ma-2" width="50%">
        <v-text-field
          label="背景が red-darken-4 の場合"
        ></v-text-field>
      </v-sheet>
      <v-sheet class="bg-blue-darken-4 ma-2" width="50%">
        <v-text-field
          label="背景が blue-darken-4 の場合"
        ></v-text-field>
      </v-sheet>
    </v-container>    

  </v-container>
</template>

v-text-field はイベント周りの実装が全然進んでない感じなので、beta9 の時点ではかなり使いづらいです。

ファイル選択:v-file-input

ローカルファイルを選択するためのコンポーネントです。

JSONファイルを読み込んで表示する

image.png

下記のコードで、JSONファイルを読み込ませてページ内に表示します。テキストファイルは、だいたい同じ方法で読めます。バイナリを読ませるときは readFile を使うと UInt8Array として読めます(多分)。

App.vue
<template>
  <v-file-input
      v-model="files"
      accept="application/json"
      @update:modelValue="readFile"
  ></v-file-input>
  <pre>
  {{ data }}
  </pre>
</template>
<script>
export default {
  data: () => ({
    files: [],
    fileReader: null,
    data: ""
  }),
  mounted(){
    this.fileReader = new FileReader();
    this.fileReader.onload = (event) => {
        this.data = JSON.parse(event.target.result);
    }
  },
  methods:{
    readFile()
    {
      if ( this.files.length == 0 ) return;
      this.fileReader.readAsText(this.files[0]);
    }
  }
}
</script>

ポイントは、v-model に与える変数を、あらかじめ [] で初期化しておくことです。バージョン2のときは、ここは配列でなくてもよかったのですが、3からは必ず配列でないとダメになりました。

ファイルを選択したときのイベントは @update:modelValue です。@change とか @update では動きません。

画像を読み込んで表示させる

v-file-input で選んだローカルファイルを canvas に表示します。

image.png

App.vue
<template>
  <v-file-input
      v-model="files"
      accept="image/*"
      @update:modelValue="readFile"
      label="画像ファイルを選択してください"
  ></v-file-input>
  <canvas id="main" width="640" height="480"></canvas>
</template>
<script>
export default {
  data: () => ({
    files: [],
  }),
  methods:{
    drawImage(src)
    {
      const canvas = document.getElementById('main');
      const ctx = canvas.getContext('2d');
      ctx.clearRect(0, 0, 640, 480 );
      const image = new Image();
      image.src = src;
      image.onload = () => {
        ctx.drawImage(image, 0, 0 );
      };
    },
    readFile()
    {
      if ( this.files.length == 0 ) return;
      const fileReader = new FileReader();
      fileReader.onload = () => {
        this.drawImage(fileReader.result);
      };
      fileReader.readAsDataURL(this.files[0]);
    }
  }
}
</script>

audio, video なども同じような方法でいけます。

スタイルは、あまり選択肢がないです。現状、TIPSを表示するとか、複数ファイル選択可能にするくらいです。

詳しくは下記を見てください。

プルダウンメニュー:v-select

クリックすると下側(もしくは上側)に項目の一覧が表示されて、そこからひとつの要素を選択できるコンポーネントです。メニューの開く方向は、コンポーネントが画面上のどこにあるかで勝手に決まります(多分)。

select1.gif

コード:

App.vue
<template>
  <v-container>
    <v-select
      :items="['hoge1','hoge2','hoge3','hoge4']"
      label="label"
      class="ma-2"
      v-model="select"
    ></v-select>
  </v-container>
</template>
<script>
export default {
  data: () => ({
    select: null,
  }),
}
</script>

コンソールに reactivity.esm-bundler.js:1092 toRefs() expects a reactive object but received a plain one. というワーニングが出る場合は、Vuetify のバージョンが古いかもしれません。package.json を見てバージョンが 3.0.0-beta.9 以上かどうかを確認してください。

スライダー:v-slider / v-range-slider

0から100までの間の値を、スライダーで選ぶことができるコンポーネントです。デフォルトでは線が白になってます。

slider1.gif

コード:

App.vue
<template>
  <v-container>
    <v-slider
      v-model="data"
      color="black"
      label="default"
    ></v-slider>
    {{ data }}
  </v-container>
</template>
<script>
export default {
  data: () => ({
    data: null,
  }),
}
</script>

初期値を与えたり、連続値でなく飛び飛びの値にすることもできます。

slider2.gif

コード:

App.vue
<template>
  <v-container>
    <v-slider
      color="black"
      v-model="data"
      :min="0"
      :max="1"
      :step="0.1"
      thumb-label
    ></v-slider>
    {{ data }}
  </v-container>
</template>
<script>
export default {
  data: () => ({
    data: 0,
  }),
}
</script>

詳しくは下記を参照してください。

ラジオボタン:v-radio-group / v-radio

いくつかの選択肢からひとつを選んでチェックを入れるコンポーネントです。

radio1.gif

App.vue
<template>
  <v-container>
    <v-radio-group v-model="radioGroup">
      <v-radio label="Hoge1" value="1"></v-radio>
      <v-radio label="Hoge2" value="2"></v-radio>
      <v-radio label="Hoge3" value="3"></v-radio>
    </v-radio-group>    
    <h1>{{ radioGroup }}</h1>
  </v-container>
</template>
<script>
export default {
  data () {
    return {
      radioGroup: "3"
    }
  },
}
</script>

<v-radio-group> の中にある <v-radio> が選択対象になります。v-radiovalue で区別されます。value が設定されていないと、チェックすることができません。同じ value を持つ v-radio を配置すると、チェックしたときに、同じ value を持つ v-radio がすべて同時に選択された状態になります。

なお、 <v-radio><v-radio-group> の直下の子要素でなくても構いません。

たとえば横に並べたいときは、以下のようにします。

image.png

App.vue
<template>
  <v-container>
    <v-radio-group>
      <div class="d-flex flex-row" >
        <v-radio label="Hoge1" value="1"></v-radio>
        <v-radio label="Hoge2" value="2"></v-radio>
        <v-radio label="Hoge3" value="3"></v-radio>
      </div>
    </v-radio-group>
  </v-container>
</template>

v-row, v-col で寄せることもできます。

d-flex で寄せる場合、v-radio-group はダミーの v-sheet なり div などで囲わないと中央寄せにはならないようです。

image.png

App.vue
<template>
  <v-container>
    <div class="d-flex justify-center">
      <div><!-- これがないと中央によらない -->
        <v-radio-group>
          <div class="d-flex flex-row" >
            <v-radio label="Hoge1" value="1"></v-radio>
            <v-radio label="Hoge2" value="2"></v-radio>
            <v-radio label="Hoge3" value="3"></v-radio>
          </div>
        </v-radio-group>
      </div>
    </div>
  </v-container>
</template>

このように、ダミーの div をひとつ挟まないと、中央に寄せることができません。

App.vue
<template>
  <v-container>
    <v-row>
      <v-col class="d-flex justify-center">
        <div><!-- これがないと中央によらない -->
        <v-radio-group>
          <v-row>
            <v-col><v-radio label="Hoge1" value="1"></v-radio></v-col>
            <v-col><v-radio label="Hoge2" value="2"></v-radio></v-col>
            <v-col><v-radio label="Hoge3" value="3"></v-radio></v-col>
          </v-row>
        </v-radio-group>
        </div>
      </v-col>
    </v-row>
  </v-container>
</template>

v-col で寄せるときも、同様にダミーの div が必要のようです。(微妙に寄り方が違います)

div を入れるより v-spacer を入れるほうが、若干(コードが)すっきりする気がします。詳しくは`Vuetify3 beta でよく使うコンポーネントのメモ(2)の記事の「横方向の空白」の項目を見てください。

チェックボックス:v-checkbox

個別の項目について、チェックを入れたり外したりできるコンポーネントです。valuev-model のどっちかが欠けていると、チェックを入れることができません。

sample2.gif

チェックした値は v-model で取得できます。チェックを入れると、v-model で指定した配列の中に value で指定した文字列が追加されます。color で指定した色は、チェックを入れるところにだけ反映されるようです。

App.vue
<template>
  <v-container>
    <v-checkbox v-model="selected" value="1" label="Hoge1">
    </v-checkbox>
    <v-checkbox v-model="selected" value="2" label="Hoge2" color="red">
    </v-checkbox>
    <v-checkbox v-model="selected" value="3" label="Hoge3" color="blue">
    </v-checkbox>
    <h1>{{selected}}</h1>
  </v-container>
</template>
<script>
export default {
  data: () => ({
    selected: []
  }),
}
</script>

他の要素と同様に、デフォルトでは縦に並びます。横に並べたければ、d-flex を使うか v-col を使います。

image.png

コード:

App.vue
<template>
  <v-container>
    <v-row>
      <v-col>
        <v-checkbox v-model="selected" value="1" label="Hoge1">
        </v-checkbox>
      </v-col>
      <v-col>
        <v-checkbox v-model="selected" value="2" label="Hoge2" color="red">
        </v-checkbox>
      </v-col>
      <v-col>
        <v-checkbox v-model="selected" value="3" label="Hoge3" color="blue">
        </v-checkbox>
      </v-col>
    </v-row>
    <h1>{{selected}}</h1>
  </v-container>
</template>
<script>
export default {
  data: () => ({
    selected: []
  }),
}
</script>

v-toolbar を使う方法もあります。v-toolbar を使うと背景色も設定できます(v-checkboxclass="bg-black" などと直接設定しても、背景色は反映されない)。

しかし、この方法できれいに並べるのはまあまあ難易度高いです。v-checkbox は下側に謎の空白があって、そのせいで普通に配置するとやたら上に寄った感じになります。マージンやパディングを設定して、density="compact" とかやって、ようやく下の図くらいになります。

image.png

コード:

App.vue
<template>
<v-toolbar class="pt-4 mt-3" density="compact" color="blue-darken-2">
  <v-spacer></v-spacer>
  <v-checkbox 
    label="hoge1" value="1" v-model="selections" density="compact">
  </v-checkbox>
  <v-checkbox 
    label="hoge2" value="2" v-model="selections" density="compact">
  </v-checkbox>
  <v-checkbox 
    label="hoge3" value="3" v-model="selections" density="compact">
  </v-checkbox>
</v-toolbar>
</template>
<script>
export default {
  data: () => (
  {
    selections: []
  }),
}
</script>

ラベルは右側にしか配置できないようです。左に配置したい場合は、テキスト無しの v-checkbox と文字列を横に並べるみたいなことをする必要があります。

ポップアップメニュー;v-menu

ボタンを押してメニューを表示させることができるコンポーネントです。プルダウンメニューと似てますが、プルダウンメニューが項目から一つを選択する用途に使われるのに対して、こちらは選択した後に、何らかのアクションを実行する用途に使われることが多い気がします。

vuetify11.gif

コード:

App.vue
<template>
  <v-container>
   <v-btn
      class="ma-3"
      color="primary"
    >
      メニューを表示するボタン

      <v-menu activator="parent">
        <v-list @click:select="clickItem">
          <v-list-item value="1">
            <v-list-item-title>Hoge1</v-list-item-title>
          </v-list-item>
          <v-list-item value="2">
            <v-list-item-title>Hoge2</v-list-item-title>
          </v-list-item>
          <v-list-item value="3">
            <v-list-item-title>Hoge3</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </v-btn>

    <h1>{{ message }}</h1>
  </v-container>
</template>
<script>
export default {
  data: () => ({
    message: null
  }),
  methods: {
    clickItem(val){
      this.message = val.id;
    }
  }
}
</script>

<v-menu> 自体はポップアップする枠だけを作る要素なので、中身は <v-list> などで別に作る必要があります。

メニューを表示させるボタンとメニューを、親子関係なしに作ることもできます。

vuetify12.gif

コード:

App.vue
<template>
 <v-container>
    <v-btn
      id="menu-activator"
      color="secondary"
    >
      ボタンとメニューを別々に配置
    </v-btn>

    <v-menu activator="#menu-activator">
      <v-list>
        <v-list-item value="1">HOGE1</v-list-item>
        <v-list-item value="2">HOGE2</v-list-item>
      </v-list>
    </v-menu>
  </v-container>
</template>

ボタンに id を設定し、その idv-menu 側の activator で指定します。

ボタンをクリックしなくても、マウスカーソルが乗っただけでメニューを出すこともできます。

vuetify13.gif

App.vue
<template>
  <v-container>
    <v-btn
      color="primary"
      id="menu-popup"
    >
      メニューボタン 
    </v-btn>
    <v-menu
      open-on-hover
      activator="#menu-popup"
    >
      <v-list>
        <v-list-item value="1">HOGE1</v-list-item>
        <v-list-item value="2">HOGE2</v-list-item>
      </v-list>
    </v-menu>
  </v-container>
</template>

v-menuopen-on-hover 属性を追加すると、マウスカーソルが乗っただけでメニューがでるようになります。

ポップアップ、ヒント表示など

ダイアログ:v-dialog

ボタンなどを押すと、画面上にポップアップするダイアログを表示します。メニューと動作的にはよく似ています。メニューに比べると、ダイアログはポップアップのオンオフ制御を、コード内からできるので、その分だけ制御の自由度が高くなっています。たとえばメニューは、アクションを実行すると勝手に閉じてしまいますが、ダイアログはボタンを押してもとじないような制御もできます。

vuetify14.gif

コード:

App.vue

<template>
  <v-container >
    <v-btn
      color="primary"
    >
      Open Dialog
      <v-dialog
        v-model="dialog"
        activator="parent"
      >
        <v-sheet>
          <v-sheet class="my-2 mx-5">
            <h2>Dialog!</h2>

            <p class="my-4">
              dialog dialog dialog dialog dialog dialog
            </p>

            <v-btn color="primary" block @click="dialog = false">Close</v-btn>
          </v-sheet>
        </v-sheet>
      </v-dialog>
    </v-btn>
  </v-container>
</template>
<script>
export default {
  data () {
    return {
      dialog: false,
    }
  },
}
</script>

ダイアログを開くコンポーネント v-btn の子要素として v-dialog を配置し、activator="parent" と指定することで、ボタンを押すと開くダイアログを作ることができます。ダイアログの表示は v-model で制御します。true にすると表示され、false とすると非表示になります。 ダイアログの中には v-sheetv-card などを置いてから、その中にダイアログの中に要素を配置します。

ボタンとダイアログを別々に作ることもできます。

vuetify15.gif

先の例とは、ダイアログが表示されるときのアニメーション(トランジション)が少し変わります。

App.vue
<template>
  <v-container >
    <v-btn
      @click="dialog = true"
      color="primary"
    >
      Open Dialog
    </v-btn>
      
    <v-dialog
      v-model="dialog"
    >
      <v-sheet>
        <v-sheet class="my-2 mx-5">
          <h2>Dialog!</h2>

          <p class="my-4">
            dialog dialog dialog dialog dialog dialog
          </p>

          <v-btn color="primary" block @click="dialog = false">Close</v-btn>
        </v-sheet>
      </v-sheet>
    </v-dialog>

  </v-container>
</template>
<script>
export default {
  data () {
    return {
      dialog: false,
    }
  },
}
</script>

メニューと同様に、ダイアログを開くボタンに id を付けて、v-dialogactivator' でその id` を指定することで、開くようにすることもできます。動作としては、上のコードと同じになります。

App.vue
<template>
  <v-container>
    <v-btn
      id="menu-popup"
      color="primary"
    >
      Open Dialog
    </v-btn>
      
    <v-dialog
      v-model="dialog"
      activator="#menu-popup"
    >
      <v-sheet>
        <v-sheet class="my-2 mx-5">
          <h2>Dialog!</h2>

          <p class="my-4">
            dialog dialog dialog dialog dialog dialog
          </p>

          <v-btn color="primary" block @click="dialog = false">Close</v-btn>
        </v-sheet>
      </v-sheet>
    </v-dialog>

  </v-container>
</template>
<script>
export default {
  data () {
    return {
      dialog: false,
    }
  },
}
</script>

複数のボタンを配置して、ボタンによって動作を変えることもできます。

vuetify16.gif

下記のコードでは OK を押すと数字を1増やし、Cancelを押したときは数字を増やしません。

App.vue
<template>
  <v-container>
    <v-btn
      @click="dialog = true"
      color="primary"
    >
      Open Dialog
    </v-btn>

    <h2>
      {{counter}}
    </h2>
      
    <v-dialog
      v-model="dialog"
    >
      <v-sheet>
        <v-sheet class="my-2 mx-5">
          <h2>Dialog!</h2>

          <p class="my-4">
            数字を1増やします。数字を1増やします。
          </p>

          <div class="d-flex justify-end my-2">
            <v-btn class="mx-2" color="primary" @click="click(true)">OK</v-btn>
            <v-btn class="mx-2" color="error" @click="click(false)">Cancel</v-btn>
          </div>
        </v-sheet>
      </v-sheet>
    </v-dialog>

  </v-container>
</template>
<script>
export default {
  data () {
    return {
      dialog: false,
      counter: 0,
    }
  },
  methods: {
    click(flag){
      if ( flag ){
        this.counter ++;
      }
      this.dialog = false;
    }
  }
}
</script>

ダイアログの詳細については下記を参照してください。

ヒントの表示:v-tooltip

ボタンなどのコンポーネントにマウスを置くと、そのコンポーネントのヒントが表示されます。

vuetify17.gif

コード:

App.vue
<template>
  <v-container class="d-flex justify-center">
    <v-btn color="primary" class="mx-3">
      ボタン
      <v-tooltip
        activator="parent"
        location="start"
      >ヒントの表示(左)</v-tooltip>
    </v-btn>

    <v-btn color="primary"  class="mx-3">
      ボタン
      <v-tooltip
        activator="parent"
        location="bottom"
      >ヒントの表示(下)</v-tooltip>
    </v-btn>
  </v-container>
</template>

ツールチップを表示させたいコンポーネントが親になるように、v-tooltop を配置して、activator="parent" を指定します。

この方法でツールチップを配置できるのは、現状 v-btn, div, span, p あたりのようです。

vuetify18.gif

コード:

App.vue
<template>
  <v-container class="d-flex justify-center">
    <div class="mx-2">
      文章のどこを触ってもヒントが出ます。      
      <v-tooltip
        activator="parent"
        location="bottom"
      >
        ヒントの表示(上)
      </v-tooltip>
    </div>

    <div class="mx-2">
      文章の途中でも
      <span class="text-red">
        ヒントを出す  
        <v-tooltip
          activator="parent"
          location="bottom"
        >
          ヒントの表示(左)
        </v-tooltip>
      </span>
      ことができます。
    </div>
  </v-container>
</template>

詳細は下記をどうぞ。

画像とアイコン

アイコン:v-icon

Material Design Icon は、Vuetify3 をインストールすれば使うことができます。

image.png

コードは、下記のどちらの方法でも同じ結果になります。

App.vue
<template>
  <v-container>
    <v-icon>
      mdi-home
    </v-icon>

    <v-icon icon="mdi-home"></v-icon>
  </v-container>
</template>

アイコンについては、下記のアイコンの項目を見てください。

公式のドキュメントは下記です。

画像:v-img

img に比べると、表示のオプションが少しリッチになっています。画像のサイズを明示的に指定しない場合、画面のサイズや親コンポーネントのサイズにあわせて、自動的に画面内に入るようにリサイズされます。

img1.gif

コード:

App.vue
<template>
  <v-container>
    <v-img src="https://cdn.vuetifyjs.com/images/parallax/material.jpg">
    </v-img>

    <div class="d-flex my-4">
    <v-img src="/images/logo.png"></v-img>
    <v-img :src="logoPNG"></v-img>
    <v-img :src="logoSVG"></v-img>
    </div>
  </v-container>
</template>
<script>
import image1 from './assets/logo.png';
import image2 from './assets/logo.svg';

export default {
  data: () => ({
    logoPNG: image1,
    logoSVG: image2,
  })
}
</script>

ただし、img タグとは微妙に挙動が違うので、用途によっては img を使ったほうがいいこともあります。

srchttphttps で指定するときは特に問題はないです。ローカルのファイルを指定するときは、下記のいずれかの方法を使う必要があります (Vue.js + npm/yarn で開発している場合)。

  • /public 以下に画像ファイルを置いて、絶対パスで指定する。
  • /src/assets 以下に画像ファイルを置いて、相対パスで import を使って読み込む。

上のソースコードでは、画像ファイルを以下のパスに置いてます。App.vue/src/App.vue に置かれているという前提です。

  • /public/images/logo.png
  • /src/assets/logo.png
  • /src/assets/logo.svg

img で表示する場合は assets に置く場合でも、import することなく、下記のコードでいけます。

ただし、下の画像のように v-img のように自動ではリサイズされません。style などで明示的に相対的なサイズを指定するなどして、画面内におさまるようにコーディングする必要があります。

img2.gif

コード:

App.vue
<template>
  <v-container>
    <img width="450" src="https://cdn.vuetifyjs.com/images/parallax/material.jpg"/>

    <div class="d-flex my-4">
    <img height="150" src="/images/logo.png"/>
    <img height="150" src="./assets/logo.png"/>
    <img height="150" src="./assets/logo.svg"/>
    </div>
  </v-container>
</template>

v-img は、ロード中にぐるぐるを表示させたり、src の URL にアクセスできないときに取り合えず表示させるデフォルトの画像を設定したり、リサイズ時のアスペクト比を固定する、しないを選択したり、などといったことができます。

詳しくは下記を見てください。

続き

34
25
1

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
34
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?