SoFunction
Updated on 2025-04-04

Writing a date picker using Vue

There are many ways to implement date selectors in Vue, and the following is a simple implementation method.

First, refer to the Vue and date-fns libraries in components that require a date picker, a lightweight JavaScript time-date tool library that can easily handle the formatting and calculation of dates.

import Vue from 'vue'
import { format } from 'date-fns'
 
export default {
  data () {
    return {
      selectedDate: null
    }
  },
  methods: {
    formatDate (date) {
      return format(date, 'yyyy-MM-dd')
    },
    selectDate (date) {
       = date
    }
  }
}

Use the third-party date picker component in the template, where the DatePicker component from the Element UI library is used. At the same time, bind the onChange event to the DatePicker component and save the selected date to the selectedDate variable in data.

<template>
  <div>
    <el-date-picker
      v-model="selectedDate"
      type="date"
      format="yyyy-MM-dd"
      @change="selectDate(selectedDate)">
    </el-date-picker>
  </div>
</template>

Define the formatDate method in methods to format the date and define the selectDate method to handle the operation of selecting a date.

import Vue from 'vue'
import { format } from 'date-fns'
 
export default {
  data () {
    return {
      selectedDate: null
    }
  },
  methods: {
    formatDate (date) {
      return format(date, 'yyyy-MM-dd')
    },
    selectDate (date) {
       = date
    }
  }
}

In this way, a simple Vue date selector is completed and can be expanded and modified according to actual needs.

Method supplement

Complete code

&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
  &lt;meta charset="UTF-8"&gt;
  &lt;title&gt;Vue Date selector&lt;/title&gt;
  &lt;style&gt;
    .datepicker {
      position: relative;
      display: inline-block;
    }
    
    .datepicker input {
      width: 120px;
      padding: 4px;
      border: 1px solid #ccc;
      outline: none;
      cursor: pointer;
    }
    
    .datepicker-panel {
      position: absolute;
      top: 30px;
      left: 0;
      z-index: 1000;
      border: 1px solid #ccc;
      background-color: #fff;
      box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.15);
    }
    
    .datepicker-content {
      padding: 10px;
    }
    
    .datepicker-header {
      margin-bottom: 10px;
      text-align: center;
    }
    
    .datepicker-header span {
      margin: 0 10px;
      cursor: pointer;
    }
    
    .datepicker-body {
      display: flex;
      flex-wrap: wrap;
      justify-content: space-between;
    }
    
    .datepicker-row {
      display: flex;
    }
    
    .datepicker-cell {
      width: calc(100% / 7);
      text-align: center;
      cursor: pointer;
    }
    
    .:hover {
      background-color: #ddd;
    }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div &gt;
  &lt;date-picker v-model="date"&gt;&lt;/date-picker&gt;
&lt;/div&gt;

&lt;script src="/npm/vue/dist/"&gt;&lt;/script&gt;
&lt;script&gt;
  ('date-picker', {
    template: `
    &lt;div class="datepicker"&gt;
      &lt;input type="text" v-model="value" @click="showPicker"&gt;
      &lt;div class="datepicker-panel" v-show="visible"&gt;
        &lt;div class="datepicker-content"&gt;
          &lt;div class="datepicker-header"&gt;
            &lt;span class="datepicker-prev-year" @click="prevYear"&gt;&amp;lt;&amp;lt;&lt;/span&gt;
            &lt;span class="datepicker-prev-month" @click="prevMonth"&gt;&amp;lt;&lt;/span&gt;
            &lt;span class="datepicker-current-month"&gt;{{ currentMonth }}&lt;/span&gt;
            &lt;span class="datepicker-next-month" @click="nextMonth"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="datepicker-next-year" @click="nextYear"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
          &lt;/div&gt;
          &lt;div class="datepicker-body"&gt;
            &lt;div class="datepicker-row" v-for="week in weeks"&gt;
              &lt;span class="datepicker-cell"
                    v-for="day in week"
                    :class="{'filled': day !== ''}"
                    @click="selectDate(day)"&gt;
                {{ day }}
              &lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  `,
    props: {
      value: {
        type: String,
        default: ''
      }
    },
    data() {
      return {
        visible: false,
        year: 0,
        month: 0,
        day: 0
      }
    },
    computed: {
      currentMonth() {
        return `${} Year ${} moon`
      },
      weeks() {
        return (, )
      }
    },
    methods: {
      showPicker() {
         = true
        const date = new Date()
         = ()
         = () + 1
         = ()
      },
      prevYear() {
        --
      },
      nextYear() {
        ++
      },
      prevMonth() {
        if ( === 1) {
          --
           = 12
        } else {
          --
        }
      },
      nextMonth() {
        if ( === 12) {
          ++
           = 1
        } else {
          ++
        }
      },
      getWeeks(year, month) {
        const weeks = []
        const firstDay = new Date(year, month - 1, 1).getDay()
        const lastDay = new Date(year, month, 0).getDate()
        let week = []
        for (let i = 0; i &lt; firstDay; i++) {
          ('')
        }
        for (let i = 1; i &lt;= lastDay; i++) {
          (i)
          if ((firstDay + i) % 7 === 0) {
            (week)
            week = []
          }
        }
        if ( &gt; 0) {
          for (let i = 0; i &lt; 7 - ; i++) {
            ('')
          }
          (week)
        }
        return weeks
      },
      selectDate(day) {
        if (day) {
           = `${}-${}-${day}`
           = false
        }
      }
    }
  })

  new Vue({
    el: '#app',
    data: {
      date: ''
    }
  })
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;

This is all about this article about writing a date selector using Vue. For more related content of Vue date selector, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!