Lightweight, high-performance calendar component based on Vue.js

Calendars play a crucial role in many web applications, from event scheduling to task management. In this detailed guide, we will embark on the journey of creating a lightweight, high-performance calendar component using Vue.js. We’ll leverage Vue.js for its reactive nature and flexibility, ensuring that our calendar not only looks sleek but also performs efficiently.

Introduction to Vue.js

Vue.js is a progressive JavaScript framework designed for building user interfaces. Its simplicity and reactivity make it an ideal choice for developing dynamic components, such as calendars. We’ll utilize Vue.js to create a responsive and performant calendar that can be seamlessly integrated into various projects.

Setting Up the Project

Start by initializing a new Vue.js project using the Vue CLI:

vue create vue-calendar-component

Navigate to the project directory:

cd vue-calendar-component

Install additional dependencies, such as Moment.js for handling dates:

npm install moment --save

Designing the Calendar Component

Create a modular structure for the calendar component. Consider breaking it down into sub-components to manage different aspects like header, days, and events.

<!-- Calendar.vue -->
<template>
  <div class="calendar">
    <CalendarHeader />
    <CalendarDays />
    <!-- Add more sub-components as needed -->
  </div>
</template>

<script>
import CalendarHeader from './CalendarHeader.vue';
import CalendarDays from './CalendarDays.vue';

export default {
  components: {
    CalendarHeader,
    CalendarDays,
    // Register additional components here
  },
  data() {
    return {
      currentDate: moment(),
      selectedDate: null,
      // Add more data properties as needed
    };
  },
  methods: {
    // Add methods for handling user interactions and events
  },
};
</script>

<style scoped>
/* Component-specific styles here */
</style>

Populating Calendar Days

Create a sub-component (CalendarDays.vue) responsible for displaying the days within the calendar.

<!-- CalendarDays.vue -->
<template>
  <div class="calendar-days">
    <!-- Display days based on the current month -->
  </div>
</template>

<script>
export default {
  props: ['currentDate', 'selectedDate'],
  data() {
    return {
      daysInMonth: [],
      // Add more data properties as needed
    };
  },
  computed: {
    // Calculate and return the days of the current month
  },
  methods: {
    // Add methods for handling user interactions and events
  },
};
</script>

<style scoped>
/* Component-specific styles here */
</style>

Styling the Calendar

Enhance the visual appeal of your calendar by adding CSS styles. Customize the styles based on the design requirements of your application.

/* Calendar.vue */
.calendar {
  max-width: 400px;
  margin: auto;
}

/* Additional styling as needed */

Incorporating Interactivity

Implement user interactions and events to make your calendar component responsive. Add methods to handle selecting dates, navigating months, and interacting with events.

<!-- CalendarDays.vue -->
<template>
  <div class="calendar-days">
    <div v-for="day in daysInMonth" :key="day.date" @click="selectDate(day)">
      {{ day.number }}
    </div>
  </div>
</template>

<script>
export default {
  props: ['currentDate', 'selectedDate'],
  data() {
    return {
      daysInMonth: [],
    };
  },
  computed: {
    // Calculate and return the days of the current month
  },
  methods: {
    selectDate(day) {
      // Handle date selection
      this.$emit('date-selected', day.date);
    },
  },
};
</script>

<style scoped>
/* Component-specific styles here */
.calendar-days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 8px;
}

.calendar-days div {
  cursor: pointer;
  padding: 8px;
  text-align: center;
  border: 1px solid #ccc;
}

.calendar-days div:hover {
  background-color: #f0f0f0;
}
</style>

Feature of calendar component based on Vue.js

  • Lightweight, high-performance calendar component based on Vue.js
  • Small memory usage, good performance, good style, and high scalability
  • Native js development, no third-party library introduced
  • Date Picker, Date Range, Multiple Calendars, Modal Calendar

There are following steps to use calendar component based on Vue.js

Install

npm i vue-functional-calendar --save

Usage

Vue.use()

// Introduced in vue file
import FunctionalCalendar from 'vue-functional-calendar';
Vue.use(FunctionalCalendar, {
    dayNames: ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su']
});

Import Component

// Introduced in vue file
import { FunctionalCalendar } from 'vue-functional-calendar';

Component Settings

export default {
    components: {
        FunctionalCalendar
    },
    data() {
        return {
            calendarData: {}
        }
    }
}

Template Usage

<FunctionalCalendar
      // v-model="calendarData"
      
      // v-on:changedMonth="changedMonth"
      // v-on:changedYear="changedYear"
      
      // :sundayStart="true"
      // :date-format="'dd/mm/yyyy'"
      // :is-date-range="true"
      // :is-date-picker="true"      
       :...:
></FunctionalCalendar>

Usage With Configs

Component Settings

export default {
    components: {
        FunctionalCalendar
    },
    data() {
        return {
            calendarData: {},
            calendarConfigs: {
                sundayStart: false,
                dateFormat: 'dd/mm/yyyy',
                isDatePicker: false,
                isDateRange: false
            }
        }
    },
}

Template Usage

<FunctionalCalendar
      // v-model="calendarData"
      // :configs="calendarConfigs"
></FunctionalCalendar>

A note on markDates

The markedDates property must be in JavaScript Date format, e.g, no leading zeroes on month and days.

✅ Correct: 1/12/2019 ❎ Incorrect: 01/12/2019

Available props

PropTypeDefaultExampleDescription
sundayStartBooleanfalsetrueWeek start sunday
newCurrentDateDatenew Date()new Date(2019,10,11)Calendar Current Date
limits[Object, Boolean]false{min: ’31/10/2019′, max: ’31/12/2019′}Set calendar show, and marked dates limits.
minSelDays[Number, Boolean]false3Set minimum selected days count.
maxSelDays[Number, Boolean]false10Set maximum selected days count.
placeholder[String, Boolean]false‘yyyy/mm/dd’Date input placeholder
dateFormatString‘dd/mm/yyyy’‘yyyy/mm/dd’Date formatting string
isDatePickerBooleanfalsetrueEnable or disable date picker
isMultipleDatePickerBooleanfalsetrueEnable or disable multiple date picker
isMultipleDateRangeBooleanfalsetrueEnable or disable multiple date range
isDateRangeBooleanfalsetrueEnable or disable date range
withTimePickerBooleanfalsetrueEnable or disable time picker
isMultipleBooleanfalsetrueEnable multiple calendar function
calendarsCountNumber13Count of calendars, working only is prop isMultiple
isSeparatelyBooleanfalsetrueEnable separately calendars
isModalBooleanfalsetrueEnable modal calendar function
isAutoCloseableBooleanfalsetrueHide picker(calendar) if date has been selected
isTypeableBooleanfalsetrueEnable manually date typing function, working only with prop isModal
changeMonthFunctionBooleanfalsetrueEnable changed month with list, function
changeYearFunctionBooleanfalsetrueEnable changed year with list, function
changeYearStepNumber126Change year list step count
changeMonthStepNumber13How many months to jump forward with NextMonth()
markedDatesArray[][’10/12/2020′, ’12/12/2020′] OR [{date: ’10/1/2020′, class: ‘marked-class’},{date: ’12/1/2020′, class: ‘marked-class-2’}]Marked dates array
markedDateRangeObject{start: false, end: false}{start: ’12/12/2020′, end: ’20/12/2020′} OR [{start: ’12/12/2020′, end: ’20/12/2020′}, {start: ’24/12/2020′, end: ’28/12/2020′}]Marked date ranges
disabledDayNamesArray[][‘Su’,’We’]Disabled Days Of Week
disabledDatesArray[][’24/12/2020′,’27/12/2020′] OR [‘beforeToday’, ‘afterToday’, ’24/12/2020′,’27/12/2020′]Disabled Dates
enabledDatesArray[][’24/12/2020′,’27/12/2020′]Reversal of Disabled Dates
dayNamesArray[‘Mo’, ‘Tu’, ‘We’, ‘Th’, ‘Fr’, ‘Sa’, ‘Su’][‘Monday’, ‘Tu’, ‘We’, ‘Th’, ‘Fr’, ‘Sa’, ‘Sunday’]Week Day Names
monthNamesArray[“January”, “February”, “March”, “April”, “May”, “June”, “July”, “August”, “September”, “October”, “November”, “December”][“Jan.”, “Feb.”, “Mar”, “Apr.”, “May”, “Jun.”, “Jul.”, “Aug.”, “Sept.”, “Oct.”, “Nov.”, “Dec.”]Month names
shortMonthNamesArray[“Jan”, “Feb”, “Mar”, “Apr”, “May”, “Jun”, “Jul”, “Aug”, “Sep”, “Oct”, “Nov”, “Dec”][“Jan.”, “Feb.”, “Mar”, “Apr.”, “May”, “Jun.”, “Jul.”, “Aug.”, “Sept.”, “Oct.”, “Nov.”, “Dec.”]Short month names
showWeekNumbersBooleanfalsetrueDisplay week numbers.
transitionBooleantruefalseCalendar animations
hiddenElementsArray[][‘dayNames’, ‘navigationArrows’, ‘leftAndRightDays’, ‘month’]Hide calendar elements
titlePositionStringcenterleft, right, centerSet title position
arrowsPositionStringspace-betweenleft, right, space-betweenSet arrows position
isDarkBooleanfalsetrueDark theme
isLayoutExpandableBooleanfalsetrueEnable expanding the calendar layout
alwaysUseDefaultClassesBooleanfalsetrueAlways add default classes to Day element, even when overriding with a slot
Available props

Slots

NameDescriptionProps
DefaultDefault slot responsible for the day component{week: Object, day: Object}
datePickerInputThis slot responsible for the modal date picker input{selectedDate: String, isTypeable: Boolean}
dateRangeInputsThis slot responsible for the modal date range inputs{startDate: String, endDate: String, isTypeable: Boolean}
footerThis slot responsible for the calendar footer{}
Slots

Events

EventOutputDescription
dayClickedObjectGet clicked day object
choseDayObjectGet the object of the selected day
changedMonthDateMonth page has been changed
changedYearDateYear page has been changed
selectedDaysCountNumberGet number of days between date range dates
dayMouseOverDateMouse over day
openedThe picker is opened
closedThe picker is closed
Events

Add the ref attribute to the calendar component and use these methods to do more

For example: <FunctionalCalendar ref="Calendar"></FunctionalCalendar>

    ✅ this.$refs.Calendar.PreMonth();  //Call method implementation to go to previous month
    ✅ this.$refs.Calendar.NextMonth(); //Call method implementation to go to next month
    ✅ this.$refs.Calendar.PreYear(); //Call method implementation to go to previous year
    ✅ this.$refs.Calendar.NextYear(); //Call method implementation to go to next year
    ✅ this.$refs.Calendar.ChooseDate('today'); //Call method implementation to go to today
    ✅ this.$refs.Calendar.ChooseDate('25/09/2020'); //Call method implementation to go to a date

Leave a Comment