---
title: "Vue Event calendar Property Reservations Example | Mobiscroll"
component: "Event calendar"
framework: "Vue"
library_version: "6.2.0"
url: "https://demo.mobiscroll.com/vue/eventcalendar/property-booking-calendar"
---

# Property Reservations - Vue Event calendar demo

Show property reservations in a monthly Vue booking calendar — exact check-in/check-out time labels, color-coded by platform. For Vue and Nuxt.

- [Live demo](https://demo.mobiscroll.com/vue/eventcalendar/property-booking-calendar)
- [View SFC JS code on GitHub](https://github.com/acidb/mobiscroll-demos-vue/tree/main/src/demos/eventcalendar/calendar-view/property-booking-calendar)
- [View SFC TS code on GitHub](https://github.com/acidb/mobiscroll-demos-vue-ts/tree/main/src/demos/eventcalendar/calendar-view/property-booking-calendar)
- This demo in other frameworks: [JavaScript](https://demo.mobiscroll.com/eventcalendar/property-booking-calendar.md), [jQuery](https://demo.mobiscroll.com/jquery/eventcalendar/property-booking-calendar.md), [Angular](https://demo.mobiscroll.com/angular/eventcalendar/property-booking-calendar.md), [React](https://demo.mobiscroll.com/react/eventcalendar/property-booking-calendar.md)

## Description

When keeping records of bookings, the event calendar with exact label displays can come in handy. The labels accurately mark the exact start (e.g. 14:00) and end times (e.g. 11:00) of bookings, consolidating all booking records in a single, clear view.

By combining the `eventDisplay: 'exact'` setting under the [`view`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-view) option with customizable [`calendarEventContent`](https://mobiscroll.com/docs/vue/eventcalendar/api#slot-calendarEventContent) , you can tailor the calendar to your specific needs. This allows you to create an efficient and user-friendly booking planning UI, ensuring all your bookings are easily managed and clearly displayed.

## What this demo shows

- A full month Eventcalendar for reservation tracking, with booking labels rendered directly inside the day cells and positioned by exact check-in and check-out times.
- **Header controls** The calendar includes standard month and year navigation, previous and next arrows, and a Today button.
- **Event labels** Reservation labels use exact timing, so they appear inside the day cells according to their start and end times.
- **Event label content** Each booking label shows the reservation guest name and the logo of the platform where the booking was made, such as Airbnb, Booking.com, or MakeMyTrip.
- **Platform colors** Label colors identify the booking platform: yellow for Airbnb, red for Booking.com, and green for MakeMyTrip.
- **Event selection** Clicking a reservation label selects it and highlights the selected booking.
- **Cell hover state** Hovering over a day cell highlights the day number in the top-right corner.
- **Day selection** Clicking empty space in a day cell selects that day and highlights the day number with a blue background.
- **Creating reservations** Double-clicking empty space or clicking and dragging across empty space creates a new event.
- **Exact-time placement** Newly created events start at 12:00 AM by default because exact label display is enabled, so they appear around the middle of the selected or dragged day cell.
- **Overlap validation** If a new reservation would overlap an existing one, the calendar shows a toast message explaining that reservations cannot overlap in the same time period.

## Best for

- **Single-unit reservation overview** Room, property, and short-stay booking interfaces where users need to see reservations directly in a month grid.
- **Reservation management** Booking systems that need to display reservations with exact time labels instead of all-day occupancy blocks.
- **Multi-platform booking records** Workflows that collect reservations from platforms such as Airbnb, Booking.com, and MakeMyTrip into one calendar view.
- **Operational overview** Monthly planning screens where users need to review existing bookings, spot availability, and keep reservation records organized.

## API used in this demo

- [`theme`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-theme) - option
- [`themeVariant`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-themeVariant) - option
- [`cssClass`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-cssClass) - option
- [`view`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-view) - option
- [`data`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-data) - option
- [`clickToCreate`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-clickToCreate) - option
- [`dragToCreate`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-dragToCreate) - option
- [`dragToMove`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-dragToMove) - option
- [`dragToResize`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-dragToResize) - option
- [`eventOverlap`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-eventOverlap) - option
- [`extendDefaultEvent`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-extendDefaultEvent) - option
- [`event-create-failed`](https://mobiscroll.com/docs/vue/eventcalendar/api#event-onEventCreateFailed) - event
- [`event-update-failed`](https://mobiscroll.com/docs/vue/eventcalendar/api#event-onEventUpdateFailed) - event
- [`close`](https://mobiscroll.com/docs/vue/notifications/toast#event-onClose) - event

## Code

### SFC JS

```vue
<script setup>
import { MbscEventcalendar, MbscToast, setOptions } from '@mobiscroll/vue'
import { ref } from 'vue'

setOptions({
  theme: 'ios',
  themeVariant: 'light'
})

const airBnB = 'https://img.mobiscroll.com/demos/air-bnb-icon.png'
const booking = 'https://img.mobiscroll.com/demos/booking-icon.png'
const makeMyTrip = 'https://img.mobiscroll.com/demos/make-my-trip-icon.png'

const myEvents = [
  {
    start: '2026-10-20T12:00',
    end: '2026-10-23T12:00',
    icon: airBnB,
    title: 'Mary Smith',
    color: '#fffa61'
  },
  {
    start: '2026-10-31T12:00',
    end: '2026-11-06T12:00',
    title: 'James Johnson',
    icon: airBnB,
    color: '#fffa61'
  },
  {
    start: '2026-10-26T12:00',
    end: '2026-10-29T12:00',
    title: 'Patricia Williams',
    icon: airBnB,
    color: '#fffa61'
  },
  {
    start: '2026-11-10T12:00',
    end: '2026-11-12T12:00',
    title: 'Michael Brown',
    icon: airBnB,
    color: '#fffa61'
  },
  {
    start: '2026-11-17T12:00',
    end: '2026-11-18T12:00',
    title: 'Jennifer Jones',
    icon: booking,
    color: '#ff9999'
  },
  {
    start: '2026-11-07T12:00',
    end: '2026-11-10T12:00',
    title: 'Robert Garcia',
    icon: booking,
    color: '#ff9999'
  },
  {
    start: '2026-11-26T12:00',
    end: '2026-11-27T12:00',
    title: 'Linda Miller',
    icon: booking,
    color: '#ff9999'
  },
  {
    start: '2026-12-03T12:00',
    end: '2026-12-04T12:00',
    title: 'John Davis',
    icon: booking,
    color: '#ff9999'
  },
  {
    start: '2026-10-23T12:00',
    end: '2026-10-25T12:00',
    title: 'Elizabeth Rodriguez',
    icon: makeMyTrip,
    color: '#a0efaa'
  },
  {
    start: '2026-11-20T12:00',
    end: '2026-11-22T12:00',
    title: 'David Martinez',
    icon: makeMyTrip,
    color: '#a0efaa'
  },
  {
    start: '2026-11-23T12:00',
    end: '2026-11-25T12:00',
    title: 'Barbara Wilson',
    icon: makeMyTrip,
    color: '#a0efaa'
  },
  {
    start: '2026-10-29T12:00',
    end: '2026-10-30T12:00',
    title: 'William Anderson',
    icon: makeMyTrip,
    color: '#a0efaa'
  },
  {
    start: '2026-11-30T12:00',
    end: '2026-12-03T12:00',
    title: 'Susan Taylor',
    icon: makeMyTrip,
    color: '#a0efaa'
  },
  {
    start: '2026-11-13T12:00',
    end: '2026-11-16T12:00',
    title: 'Richard Jackson',
    icon: airBnB,
    color: '#fffa61'
  }
]

const myView = {
  calendar: {
    type: 'month',
    eventDisplay: 'exact'
  }
}

const isToastOpen = ref(false)

function customDefaultEvent(args) {
  const start = new Date(args.start.setHours(12))
  const end = new Date(
    args.start.getFullYear(),
    args.start.getMonth(),
    args.start.getDate() + 1,
    12
  )
  return {
    title: 'New reservation',
    start,
    end
  }
}
</script>

<template>
  <MbscEventcalendar
    cssClass="mds-booking-calendar"
    :view="myView"
    :data="myEvents"
    :clickToCreate="true"
    :dragToCreate="true"
    :dragToMove="true"
    :dragToResize="true"
    :eventOverlap="false"
    :extendDefaultEvent="customDefaultEvent"
    @event-create-failed="isToastOpen = true"
    @event-update-failed="isToastOpen = true"
  >
    <template #calendarEventContent="event">
      <div class="mbsc-flex mds-booking-item mbsc-align-items-center">
        <img
          v-if="event.original.icon"
          class="mds-booking-icon"
          draggable="false"
          :src="event.original.icon"
        />
        <span>{{ event.title }}</span>
      </div>
    </template>
  </MbscEventcalendar>
  <MbscToast
    message="Reservations cannot overlap"
    :isOpen="isToastOpen"
    @close="isToastOpen = false"
  />
</template>

<style>
.mds-booking-calendar .mbsc-calendar-day .mbsc-calendar-text {
  height: 30px;
  line-height: 30px;
  margin: 0 0.2em 0.2em 0.3em;
}

.mds-booking-item {
  font-size: 16px;
}

.mds-booking-icon {
  margin-right: 8px;
  width: 24px;
  height: 24px;
}
</style>
```

### SFC TS

```vue
<script setup lang="ts">
import { MbscEventcalendar, setOptions } from '@mobiscroll/vue'
import type { MbscCalendarEvent, MbscEventcalendarView, MbscNewEventData } from '@mobiscroll/vue'
import { ref } from 'vue'

setOptions({
  theme: 'ios',
  themeVariant: 'light'
})

const airBnB = 'https://img.mobiscroll.com/demos/air-bnb-icon.png'
const booking = 'https://img.mobiscroll.com/demos/booking-icon.png'
const makeMyTrip = 'https://img.mobiscroll.com/demos/make-my-trip-icon.png'

const myEvents: MbscCalendarEvent[] = [
  {
    start: '2026-10-20T12:00',
    end: '2026-10-23T12:00',
    icon: airBnB,
    title: 'Mary Smith',
    color: '#fffa61'
  },
  {
    start: '2026-10-31T12:00',
    end: '2026-11-06T12:00',
    title: 'James Johnson',
    icon: airBnB,
    color: '#fffa61'
  },
  {
    start: '2026-10-26T12:00',
    end: '2026-10-29T12:00',
    title: 'Patricia Williams',
    icon: airBnB,
    color: '#fffa61'
  },
  {
    start: '2026-11-10T12:00',
    end: '2026-11-12T12:00',
    title: 'Michael Brown',
    icon: airBnB,
    color: '#fffa61'
  },
  {
    start: '2026-11-17T12:00',
    end: '2026-11-18T12:00',
    title: 'Jennifer Jones',
    icon: booking,
    color: '#ff9999'
  },
  {
    start: '2026-11-07T12:00',
    end: '2026-11-10T12:00',
    title: 'Robert Garcia',
    icon: booking,
    color: '#ff9999'
  },
  {
    start: '2026-11-26T12:00',
    end: '2026-11-27T12:00',
    title: 'Linda Miller',
    icon: booking,
    color: '#ff9999'
  },
  {
    start: '2026-12-03T12:00',
    end: '2026-12-04T12:00',
    title: 'John Davis',
    icon: booking,
    color: '#ff9999'
  },
  {
    start: '2026-10-23T12:00',
    end: '2026-10-25T12:00',
    title: 'Elizabeth Rodriguez',
    icon: makeMyTrip,
    color: '#a0efaa'
  },
  {
    start: '2026-11-20T12:00',
    end: '2026-11-22T12:00',
    title: 'David Martinez',
    icon: makeMyTrip,
    color: '#a0efaa'
  },
  {
    start: '2026-11-23T12:00',
    end: '2026-11-25T12:00',
    title: 'Barbara Wilson',
    icon: makeMyTrip,
    color: '#a0efaa'
  },
  {
    start: '2026-10-29T12:00',
    end: '2026-10-30T12:00',
    title: 'William Anderson',
    icon: makeMyTrip,
    color: '#a0efaa'
  },
  {
    start: '2026-11-30T12:00',
    end: '2026-12-03T12:00',
    title: 'Susan Taylor',
    icon: makeMyTrip,
    color: '#a0efaa'
  },
  {
    start: '2026-11-13T12:00',
    end: '2026-11-16T12:00',
    title: 'Richard Jackson',
    icon: airBnB,
    color: '#fffa61'
  }
]

const myView: MbscEventcalendarView = {
  calendar: {
    type: 'month',
    eventDisplay: 'exact'
  }
}

const isToastOpen = ref(false)

function customDefaultEvent(args: MbscNewEventData) {
  const start = new Date(args.start.setHours(12))
  const end = new Date(
    args.start.getFullYear(),
    args.start.getMonth(),
    args.start.getDate() + 1,
    12
  )
  return {
    title: 'New reservation',
    start,
    end
  }
}
</script>

<template>
  <MbscEventcalendar
    cssClass="mds-booking-calendar"
    :view="myView"
    :data="myEvents"
    :clickToCreate="true"
    :dragToCreate="true"
    :dragToMove="true"
    :dragToResize="true"
    :eventOverlap="false"
    :extendDefaultEvent="customDefaultEvent"
    @event-create-failed="isToastOpen = true"
    @event-update-failed="isToastOpen = true"
  >
    <template #calendarEventContent="event">
      <div class="mbsc-flex mds-booking-item mbsc-align-items-center">
        <img
          v-if="event.original.icon"
          class="mds-booking-icon"
          draggable="false"
          :src="event.original.icon"
        />
        <span>{{ event.title }}</span>
      </div>
    </template>
  </MbscEventcalendar>
  <MbscToast
    message="Reservations cannot overlap"
    :isOpen="isToastOpen"
    @close="isToastOpen = false"
  />
</template>

<style>
.mds-booking-calendar .mbsc-calendar-day .mbsc-calendar-text {
  height: 30px;
  line-height: 30px;
  margin: 0 0.2em 0.2em 0.3em;
}

.mds-booking-item {
  font-size: 16px;
}

.mds-booking-icon {
  margin-right: 8px;
  width: 24px;
  height: 24px;
}
</style>
```

## Implementation notes

- Use `calendar: { type: 'month', eventDisplay: 'exact' }` in the view config so each booking renders as a proportional bar spanning its exact check-in-to-check-out date range.
- Give each event a custom `icon` property (platform logo URL), a `title` (guest name), a per-platform `color`, and `start`/`end` both set to 12:00 to represent noon check-in and noon check-out.
- Use `renderCalendarEventContent` (Angular: `calendarEventContentTemplate`, Vue: `calendarEventContent`) to render each label as the platform icon image followed by the guest name.
- Set `extendDefaultEvent` to snap newly created reservations to noon boundaries: set `start` to 12:00 on the drag-start day and `end` to 12:00 on the following day.
- Enable `clickToCreate`, `dragToCreate`, `dragToMove`, and `dragToResize`; set `eventOverlap: false` to prevent bookings from overlapping.
- In `onEventCreateFailed` and `onEventUpdateFailed`, show a `Toast` with an overlap error message.

## Run it in your project

1. If not signed up yet, or don't own a license, you can [start a free trial](https://mobiscroll.com/starttrial).

2. Clone the repository:

   ```
   git clone https://github.com/acidb/mobiscroll-demos-vue.git
   ```

3. If not installed yet, install the Mobiscroll CLI from NPM:

   ```
   npm install -g @mobiscroll/cli
   ```

4. Config Mobiscroll - open a terminal window in the root directory and run:

   ```
   mobiscroll config vue
   ```

5. Install dependencies - open a terminal window in the root directory and run:

   ```
   npm install
   ```

6. Run the project:

   ```
   npm run dev
   ```

On a trial, add `--trial` to the config command: `mobiscroll config vue --trial`.

Running a demo locally requires a Mobiscroll trial or a license; setup is per framework at https://mobiscroll.com/docs/vue/getting-started/installation

## Related demos

- Next: [Day Cell Summary View](https://demo.mobiscroll.com/vue/eventcalendar/day-cell-aggregate-information.md) - Show color-coded daily event summaries in the Vue event calendar — each cell displays meeting counts and workload density.
