みなさん、こんにちは。どんぶラッコです。
今回は Vuetify v2 を使って、このようなテキストフィールドを作ってみましょう。
v-text-field
コンポーネントとv-date-picker
コンポーネントの2つを使うことで実現できます。
早速、サンプルコードをみていきましょう!
サンプルと解説
実際に動くコードについてはcodesandbox上にアップロードしてあります。
App.vue
<template>
<v-app>
<v-content>
<v-row justify="center">
<v-col cols="8">
<v-text-field v-model="value" single-line>
<template v-slot:append-outer>
<date-picker v-model="value"/>
</template>
</v-text-field>
</v-col>
<v-col cols="8">
<p>日付: {{ value }}</p>
</v-col>
</v-row>
</v-content>
</v-app>
</template>
<script>
import DatePicker from "./components/DatePicker";
export default {
name: "App",
components: {
DatePicker
},
data() {
return {
value: null
};
}
};
</script>
ここでは、 v-text-field
の表示設定をしています。
<v-text-field v-model="value" single-line>
<template v-slot:append-outer>
<date-picker v-model="value"/>
</template>
</v-text-field>
このように、v-slot:append-outer
を使うことで、テキストフィールドのお尻の部分にUI表示を追加しています。
そこでは date-picker
コンポーネントを描画するように指示を出しています。
(date-pickerコンポーネントを読み込んでいるのは↓の部分です!)
<script>
import DatePicker from "./components/DatePicker";
export default {
components: {
DatePicker
},
...
};
</script>
components/DatePicker.vue
では次にDatePickerの中身をみていきましょう。
<template>
<v-menu v-model="menu" offset-y :close-on-content-click="false">
<template v-slot:activator="{ on }">
<v-btn icon color="primary" dark elevation="0" v-on="on">
<v-icon>mdi-calendar</v-icon>
</v-btn>
</template>
<v-date-picker v-model="picker" @click="menu = false"/>
</v-menu>
</template>
<script>
export default {
props: {
value: {
type: String,
default: new Date().toISOString().substr(0, 10)
}
},
data() {
return {
menu: false
};
},
computed: {
picker: {
get() {
return this.value;
},
set(val) {
this.menu = false;
this.$emit("input", val);
}
}
}
};
</script>
手順ごとに分解していきましょう。
1. カレンダーのボタンを作る
カレンダーアイコンが表示されているボタンを作ります。
<v-btn icon color="primary" dark elevation="0" v-on="on">
<v-icon>mdi-calendar</v-icon>
</v-btn>
2. ①で作成したボタンをメニューのトリガーにする
v-menu
のトリガーとしてボタンを設定します。
<v-menu v-model="menu" offset-y :close-on-content-click="false">
<template v-slot:activator="{ on }">
<v-btn icon color="primary" dark elevation="0" v-on="on">
<v-icon>mdi-calendar</v-icon>
</v-btn>
</template>
</v-menu>
3. メニューとして表示される対象に v-date-picker を指定する
<v-menu v-model="menu" offset-y :close-on-content-click="false">
<template v-slot:activator="{ on }">
<v-btn icon color="primary" dark elevation="0" v-on="on">
<v-icon>mdi-calendar</v-icon>
</v-btn>
</template>
<v-date-picker v-model="picker" @click="menu = false"/> <!-- ここを追加したよ! -->
</v-menu>
以上の3ステップでこのコンポーネントが成り立っています。
あとは、v-date-picker
が日付を拾ってきてくれたら $emit
の機能を使って親コンポーネントにお知らせしてあげるだけです。
今回は v-date-picker
のv-model
に設定してる picker
を computed
で指定することで 値渡しを実現しています。
computed: {
picker: {
get() {
return this.value;
},
set(val) {
this.menu = false;
this.$emit("input", val);
}
}
}
以上、サンプルコードでした!
みなさんもぜひ試してみてください♪
より体系的にインプットしたい方は、こちらの書籍がおすすめです。周りの初学者には必ず勧めている書籍です!
すみません。Veautify勉強中です。
App.vueの中でDatePicker呼び出してなくないですか?
date-pickerを呼び出しているように見えます。
Vueの命名規則の特性として、”DatePicker”として読み込んだコンポーネントは
パスカルケース(DatePicker)・ケバブケース(date-picker)どちらでも呼び出すことができますよ!
なので、 DatePicker と書いても date-picker と書いてもどちらも正解です。
※このQiita記事がわかりやすいです!
https://qiita.com/ngron/items/ab2a17ae483c95a2f15e
お返事ありがとうございます。
なるほど。とても勉強になりました。
私も無事再現できました!
しかし、v-data-tableの中に表示しようとするとアイコンが表示されません。
テキストフィールドのみ表示されます。
“`
“`
のような形で描画するスロットを指定しています。
すみませんが教えて頂けないでしょうか。
うまくコードが添付できていないようです。。
想像するに、v-slotが競合してしまっているのではないかと思っています。
お作りいただいたDatePicker付きの v-text-field をコンポーネント化してv-data-tableに埋め込んでも表示されませんか?