環境 Vue 2.6.11 Vuetify 2.4.0
実装した時の備忘録なのでメモが粗いです。。
もっといい書き方があればコメントいただければ嬉しいです!
やりたいこと
Vuetify
の select form
を使って生年月日の入力フォームを作りたい
イメージ1
年もしくは月が変わったら、選択されている日をクリアして選択し直すようにする
イメージ2
package.json
{
"name": "sample-app",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^3.6.5",
"vue": "^2.6.11",
"vue-router": "^3.2.0",
"vuetify": "^2.4.0",
"vuex": "^3.4.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/eslint-config-prettier": "^6.0.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^6.2.2",
"prettier": "^2.2.1",
"sass": "^1.32.0",
"sass-loader": "^10.0.0",
"vue-cli-plugin-vuetify": "~2.3.1",
"vue-template-compiler": "^2.6.11",
"vuetify-loader": "^1.7.0"
}
}
実装
<template>
<v-card width="480">
<v-card-text>
<div class="mb-4">- 生年月日 -</div>
<v-row>
<v-col cols="6">
<v-select label="西暦" :items="years" v-model="year" @change="resetDay" filled dense></v-select>
</v-col>
<v-col cols="3">
<v-select label="月" :items="months" v-model="month" @change="resetDay" filled dense></v-select>
</v-col>
<v-col cols="3">
<v-select label="日" :items="days" v-model="day" filled dense></v-select>
</v-col>
</v-row>
<div class="text-center">
<v-btn class="ma-2" color="teal" dark>次へ</v-btn>
</div>
</v-card-text>
<pre>{{ $data }}</pre>
</v-card>
</template>
<script>
export default {
data: () => ({
year: '',
month: '',
day: '',
}),
methods: {
resetDay() {
this.day = ''
},
},
computed: {
years() {
const years = []
for (let year = 1900; year <= new Date().getFullYear(); year++) {
years.push(year)
}
return years
},
months() {
const months = [...Array(12)].map((ele, i) => i + 1)
return months
},
days() {
let days = []
if ((this.month === 2 && this.year % 4 === 0 && this.year % 100 !== 0) || (this.month === 2 && this.year % 400 === 0)) {
days = [...Array(29)].map((ele, i) => i + 1)
} else if (this.month === 2) {
days = [...Array(28)].map((ele, i) => i + 1)
} else if (this.month === 4 || this.month === 6 || this.month === 9 || this.month === 11) {
days = [...Array(30)].map((ele, i) => i + 1)
} else {
days = [...Array(31)].map((ele, i) => i + 1)
}
return days
},
},
}
</script>
メモ
- 入力フォームはVuetifyのSelectsコンポーネントを使用
- 年はyears、月はmonths、日はdaysとしてcomputedプロパティで管理
- 年は、1900年〜今年(
new Date().getFullYear()
)までが表示するようにしている - 月は、1〜12の整数を配列に入れる方法を
[...Array(12)].map((ele, i) => i + 1)
で実装 ※参考記事 ワンライナーで0から10の値を持つ配列を作る方法 - 年もしくは月が変わったら、v-onでchangeイベントを発火、
@change="resetDay"
と記述してresetDayメソッド
を定義、入力している日をクリアする - うるう年の換算は以下で実装
let days = []
if ((this.month === 2 && this.year % 4 === 0 && this.year % 100 !== 0) || (this.month === 2 && this.year % 400 === 0)) {
days = [...Array(29)].map((ele, i) => i + 1)
} else if (this.month === 2) {
days = [...Array(28)].map((ele, i) => i + 1)
} else if (this.month === 4 || this.month === 6 || this.month === 9 || this.month === 11) {
days = [...Array(30)].map((ele, i) => i + 1)
} else {
days = [...Array(31)].map((ele, i) => i + 1)
}