vue の datepicker で アイコンをクリックしてカレンダーを表示する

インポートとプロパティ

インポートとプロパティの設定をします。

import Datepicker from 'vuejs-datepicker';
import {ja} from 'vuejs-datepicker/dist/locale';
import moment from "moment";
export default {
    name: 'hoge',
    components: {
        Datepicker,
    },
    data() {
        return {
            ja:ja,
            calendarDate: null,
        }
    },

テンプレート

テンプレートは下記のとおりです。

<div class="menu-icon-wrapper" v-on:click="calendar()"><img class="icon" src="@/assets/calendar.png"></div>
<Datepicker
    ref="datepicker"
    :monday-first="true"
    :language="ja"
    wrapper-class="calender-text-box-wrapper"
    input-class="calender-text-box"
    placeholder=""
    format="yyyy-MM-dd"
    @selected=dateSelected
/>
<input type="text" v-model="calendarDate">

下記の部分はアイコンを設置しています。
アイコンをクリックするとcalendar()を呼び出してカレンダーの開閉をします。

<div class="menu-icon-wrapper" v-on:click="calendar()"><img class="icon" src="@/assets/calendar.png"></div>

下記の部分は datepicker です。
@selected=dateselected部分でカレンダーにて日付が選択された時にdateSelectedを呼び出しています。

<Datepicker
    ref="datepicker"
    :monday-first="true"
    :language="ja"
    wrapper-class="calender-text-box-wrapper"
    input-class="calender-text-box"
    placeholder=""
    format="yyyy-MM-dd"
    @selected=dateSelected
/>

メソッド

メソッドは下記のとおりです。

methods: {
    calendar() {
        if(!this.$refs.datepicker.isOpen) {
            this.$refs.datepicker.$el.querySelector("input").focus();
            this.$refs.datepicker.showCalendar();
        } else {
            this.$refs.datepicker.close();
        }
    },
    dateSelected(selectedDate) {
        this.calendarDate = moment(selectedDate).format('YYYY-MM-DD');
    },

calendar()は、アイコンをクリックされたときに呼び出されます。
カレンダーが閉じていれば「カレンダーを開く」カレンダーが開いていれば「カレンダーを閉じる」という動作をしています。

dateSeleccted(selectedDate)は、カレンダーの日付が選択されたときに呼び出されます。
受け取った引数には選択された日付が格納されています。
<Datepicker>内でフォーマットを指定していても datepicker のコンポーネント外だとフォーマットが崩れてしまうようなのでmomentでフォーマットを新たに指定しています。

スタイル

デザインは下記のとおりです。
テンプレートに<input type="text" v-model="calendarDate">がある為、datepicker コンポーネントが持つテキストボックスは不要になったので display: none で非表示にします。

<style>
    .calender-text-box-wrapper{
    }
    .calender-text-box {
        display: none;
    }
    .vdp-datepicker__calendar {
        width: 100% !important;
    }
</style>

最後に

datepicker コンポーネントから「テキストボックスクリック時にカレンダー表示」と「コンポーネントが持つテキストボックスに値をインプットする」というデフォルトの動作をカスタマイズする事が出来ました。
もっと他に良い方法があれば教えて頂きたいです。。。

YouTube