DevExtreme v24.1 is now available.

Explore our newest features/capabilities and share your thoughts with us.

Your search did not match any results.

Vue Scheduler - Overview

DevExtreme Scheduler is a versatile scheduling component. Its main features include appointment editing, time zones support, vertical and horizontal orientation, and many more. You can use Vue syntax and techniques to instantiate and configure the Scheduler or handle its events. In addition, the component supports prop validation and templates that use named slots. Find out more about DevExtreme Vue components.

To get started with the DevExtreme Scheduler component, refer to the following tutorial for step-by-step instructions: Getting Started with Scheduler.

Backend API
<template> <DxScheduler time-zone="America/Los_Angeles" :data-source="dataSource" :current-date="currentDate" :views="views" :groups="groups" :height="600" :show-all-day-panel="true" :first-day-of-week="1" :start-day-hour="8" :end-day-hour="18" current-view="month" data-cell-template="dataCellTemplate" resource-cell-template="resourceCellTemplate" > <DxResource :data-source="employees" :allow-multiple="false" label="Employee" field-expr="employeeID" /> <template #resourceCellTemplate="{ data: employee }"> <ResourceCell :employee="employee" /> </template> <template #dataCellTemplate="{ data: cellData }"> <DataCell :cell-data="cellData" /> </template> </DxScheduler> </template> <script setup lang="ts"> import { DxScheduler, DxResource } from 'devextreme-vue/scheduler'; import { employees, data } from './data.ts'; import DataCell from './DataCell.vue'; import ResourceCell from './ResourceCell.vue'; const groups = ['employeeID']; const views = ['month']; const currentDate = new Date(2021, 5, 2, 11, 30); const dataSource = data; </script> <style> .dx-scheduler-group-header, .dx-scheduler-date-table-cell { position: relative; } .dx-scheduler-date-table-other-month.dx-scheduler-date-table-cell { opacity: 1; color: rgba(0, 0, 0, 0.3); } .dx-scheduler-date-table-cell .dx-template-wrapper { position: absolute; width: 100%; height: 100%; padding-right: 6px; } </style>
<template> <div :class="markWeekEnd(cellData)" > <div :class="markTraining(cellData)"> {{ cellData.text }} </div> </div> </template> <script setup lang="ts"> withDefaults(defineProps<{ cellData?: any }>(), { cellData: () => {}, }); function markWeekEnd(cellData) { function isWeekEnd(date) { const day = date.getDay(); return day === 0 || day === 6; } const classObject = {}; classObject[`employee-${cellData.groups.employeeID}`] = true; classObject[`employee-weekend-${cellData.groups.employeeID}`] = isWeekEnd(cellData.startDate); return classObject; } function markTraining(cellData) { const classObject = { 'day-cell': true, }; classObject[ getCurrentTraining(cellData.startDate.getDate(), cellData.groups.employeeID) ] = true; return classObject; } function getCurrentTraining(date, employeeID) { const result = (date + employeeID) % 3; const currentTraining = `training-background-${result}`; return currentTraining; } </script> <style> .day-cell { height: 100%; background-position: center center; background-repeat: no-repeat; } .employee-1 { background-color: rgba(86, 202, 133, 0.1); } .employee-2 { background-color: rgba(255, 151, 71, 0.1); } .employee-weekend-1 { background-color: rgba(86, 202, 133, 0.2); } .employee-weekend-2 { background-color: rgba(255, 151, 71, 0.2); } .training-background-0 { background-image: url("../../../../images/gym/icon-abs.png"); } .training-background-1 { background-image: url("../../../../images/gym/icon-step.png"); } .training-background-2 { background-image: url("../../../../images/gym/icon-fitball.png"); } </style>
<template> <div> <div :style="'background:' + employee.color" class="name" > <h2>{{ employee.text }}</h2> </div> <div class="avatar"> <img :src="employee.data.avatar"> </div> <div :style="'color:' + employee.color" class="info" > Age: {{ employee.data.age }} <br> <b>{{ employee.data.discipline }}</b> </div> </div> </template> <script setup lang="ts"> withDefaults(defineProps<{ employee?: any }>(), { employee: () => {}, }); </script> <style> .avatar { width: 155px; float: left; overflow: hidden; position: relative; height: 125px; } .name { position: absolute; bottom: 0; left: 0; width: 100%; } .name h2 { color: #fff; font-size: 28px; text-align: left; padding: 0 0 5px 175px; margin: 0; } .info { width: auto; text-align: left; height: 100%; font-size: 11pt; font-weight: normal; padding: 25px 20px; color: #707070; } .dx-color-scheme-contrast .info { color: #fff; } </style>
window.exports = window.exports || {}; window.config = { transpiler: 'plugin-babel', meta: { '*.vue': { loader: 'vue-loader', }, '*.ts': { loader: 'demo-ts-loader', }, '*.svg': { loader: 'svg-loader', }, 'devextreme/time_zone_utils.js': { 'esModule': true, }, 'devextreme/localization.js': { 'esModule': true, }, 'devextreme/viz/palette.js': { 'esModule': true, }, }, paths: { 'root:': '../../../../', 'npm:': 'https://unpkg.com/', }, map: { 'vue': 'npm:vue@3.2.47/dist/vue.esm-browser.js', 'vue-loader': 'npm:dx-systemjs-vue-browser@1.1.1/index.js', 'demo-ts-loader': 'root:utils/demo-ts-loader.js', 'svg-loader': 'root:utils/svg-loader.js', 'mitt': 'npm:mitt/dist/mitt.umd.js', 'rrule': 'npm:rrule@2.6.4/dist/es5/rrule.js', 'luxon': 'npm:luxon@1.28.1/build/global/luxon.min.js', 'es6-object-assign': 'npm:es6-object-assign@1.1.0', 'devextreme': 'npm:devextreme@24.1.6/cjs', 'devextreme-vue': 'npm:devextreme-vue@24.1.6/cjs', 'jszip': 'npm:jszip@3.10.1/dist/jszip.min.js', 'devextreme-quill': 'npm:devextreme-quill@1.7.1/dist/dx-quill.min.js', 'devexpress-diagram': 'npm:devexpress-diagram@2.2.11/dist/dx-diagram.js', 'devexpress-gantt': 'npm:devexpress-gantt@4.1.56/dist/dx-gantt.js', '@devextreme/runtime': 'npm:@devextreme/runtime@3.0.13', 'inferno': 'npm:inferno@7.4.11/dist/inferno.min.js', 'inferno-compat': 'npm:inferno-compat/dist/inferno-compat.min.js', 'inferno-create-element': 'npm:inferno-create-element@7.4.11/dist/inferno-create-element.min.js', 'inferno-dom': 'npm:inferno-dom/dist/inferno-dom.min.js', 'inferno-hydrate': 'npm:inferno-hydrate@7.4.11/dist/inferno-hydrate.min.js', 'inferno-clone-vnode': 'npm:inferno-clone-vnode/dist/inferno-clone-vnode.min.js', 'inferno-create-class': 'npm:inferno-create-class/dist/inferno-create-class.min.js', 'inferno-extras': 'npm:inferno-extras/dist/inferno-extras.min.js', 'plugin-babel': 'npm:systemjs-plugin-babel@0.0.25/plugin-babel.js', 'systemjs-babel-build': 'npm:systemjs-plugin-babel@0.0.25/systemjs-babel-browser.js', // Prettier 'prettier/standalone': 'npm:prettier@2.8.8/standalone.js', 'prettier/parser-html': 'npm:prettier@2.8.8/parser-html.js', }, packages: { 'devextreme-vue': { main: 'index.js', }, 'devextreme': { defaultExtension: 'js', }, 'devextreme/events/utils': { main: 'index', }, 'devextreme/events': { main: 'index', }, 'es6-object-assign': { main: './index.js', defaultExtension: 'js', }, }, packageConfigPaths: [ 'npm:@devextreme/*/package.json', 'npm:@devextreme/runtime@3.0.13/inferno/package.json', ], babelOptions: { sourceMaps: false, stage0: true, }, }; System.config(window.config);
export const employees = [{ text: 'John Heart', id: 1, color: '#56ca85', avatar: '../../../../images/gym/coach-man.png', age: 27, discipline: 'ABS, Fitball, StepFit', }, { text: 'Sandra Johnson', id: 2, color: '#ff9747', avatar: '../../../../images/gym/coach-woman.png', age: 25, discipline: 'ABS, Fitball, StepFit', }]; export const data = [ { text: 'Helen', employeeID: 2, startDate: new Date('2021-06-01T16:30:00.000Z'), endDate: new Date('2021-06-01T18:30:00.000Z'), }, { text: 'Helen', employeeID: 2, startDate: new Date('2021-06-10T16:30:00.000Z'), endDate: new Date('2021-06-11T18:30:00.000Z'), }, { text: 'Alex', employeeID: 1, startDate: new Date('2021-06-02T16:30:00.000Z'), endDate: new Date('2021-06-02T18:30:00.000Z'), }, { text: 'Alex', employeeID: 1, startDate: new Date('2021-06-11T19:00:00.000Z'), endDate: new Date('2021-06-11T20:00:00.000Z'), }, { text: 'Alex', employeeID: 2, startDate: new Date('2021-06-16T16:30:00.000Z'), endDate: new Date('2021-06-16T18:30:00.000Z'), }, { text: 'Stan', employeeID: 1, startDate: new Date('2021-06-07T16:30:00.000Z'), endDate: new Date('2021-06-07T18:30:00.000Z'), }, { text: 'Stan', employeeID: 1, startDate: new Date('2021-06-28T16:30:00.000Z'), endDate: new Date('2021-06-28T18:30:00.000Z'), }, { text: 'Stan', employeeID: 1, startDate: new Date('2021-06-30T16:30:00.000Z'), endDate: new Date('2021-06-30T18:30:00.000Z'), }, { text: 'Rachel', employeeID: 2, startDate: new Date('2021-06-04T16:30:00.000Z'), endDate: new Date('2021-06-04T18:30:00.000Z'), }, { text: 'Rachel', employeeID: 2, startDate: new Date('2021-06-07T16:30:00.000Z'), endDate: new Date('2021-06-07T18:30:00.000Z'), }, { text: 'Rachel', employeeID: 1, startDate: new Date('2021-06-21T16:30:00.000Z'), endDate: new Date('2021-06-21T18:30:00.000Z'), }, { text: 'Kelly', employeeID: 2, startDate: new Date('2021-06-15T16:30:00.000Z'), endDate: new Date('2021-06-15T18:30:00.000Z'), }, { text: 'Kelly', employeeID: 2, startDate: new Date('2021-06-29T16:30:00.000Z'), endDate: new Date('2021-06-29T18:30:00.000Z'), }, ];
import { createApp } from 'vue'; import App from './App.vue'; createApp(App).mount('#app');
<!DOCTYPE html> <html lang="en"> <head> <title>DevExtreme Demo</title> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/24.1.6/css/dx.light.css" /> <script src="https://unpkg.com/typescript@4.9.5/lib/typescript.js"></script> <script type="module"> import * as vueCompilerSFC from "https://unpkg.com/@vue/compiler-sfc@3.4.16/dist/compiler-sfc.esm-browser.js"; window.vueCompilerSFC = vueCompilerSFC; </script> <script src="https://unpkg.com/core-js@2.6.12/client/shim.min.js"></script> <script src="https://unpkg.com/systemjs@0.21.3/dist/system.js"></script> <script type="text/javascript" src="config.js"></script> <script type="text/javascript"> System.import("./index.ts"); </script> </head> <body class="dx-viewport"> <div class="demo-container"> <div id="app"> </div> </div> </body> </html>