Categories
React

Add a Modal to a React App with react-modal and react-confirm-alert

Modals are something that we have to add often into our React app.

To make this task easier, we can use existing component libraries to add them.

In this article, we’ll look at how to add a modal into our React app with the react-modal and react-confirm-alert libraries.

Installation

We can install the library by running:

npm install --save react-modal

with NPM or:

yarn add react-modal

with Yarn.

Usage

We can use it by adding the Modal component into our React component.

To do this, we write:

import React from "react";
import Modal from "react-modal";

const customStyles = {
  content: {
    top: "50%",
    left: "50%",
    right: "auto",
    bottom: "auto",
    marginRight: "-50%",
    transform: "translate(-50%, -50%)"
  }
};

Modal.setAppElement("#root");

export default function App() {
  let subtitle;

  const [modalIsOpen, setIsOpen] = React.useState(false);
  function openModal() {
    setIsOpen(true);
  }

  function afterOpenModal() {
    subtitle.style.color = "#f00";
  }

  function closeModal() {
    setIsOpen(false);
  }

  return (
    <div>
      <button onClick={openModal}>Open Modal</button>
      <Modal
        isOpen={modalIsOpen}
        onAfterOpen={afterOpenModal}
        onRequestClose={closeModal}
        style={customStyles}
        contentLabel="Example Modal"
      >
        <h2 ref={(_subtitle) => (subtitle = _subtitle)}>Hello</h2>
        <button onClick={closeModal}>close</button>
        <div>I am a modal</div>
        <form>
          <input />
          <br />
          <button>ok</button>
          <button>cancel</button>
        </form>
      </Modal>
    </div>
  );
}

We add the customStyles object to style the items.

And we add the modalIsOpen state to control when the modal opens or closes.

The isOpen prop controls whether the modal is opened or closed.

onAfterOpen takes a function that runs code after the modal is open.

onRequestClose takes a function that runs code after the modal is closed.

style takes an object with some properties to change the styles.

contentLabel is a label for the modal.

We call Modal.setAppElement(“#root”) to make the modal component attach to the element with ID root .

react-confirm-alert

The react-confirm-alert library is another library that lets us add a modal easily into our React app.

To install it, we run:

npm install react-confirm-alert --save

We can use it by writing:

import React from "react";
import { confirmAlert } from "react-confirm-alert";
import "react-confirm-alert/src/react-confirm-alert.css";

export default function App() {
  const submit = () => {
    confirmAlert({
      title: "Confirm to submit",
      message: "Are you sure to do this.",
      buttons: [
        {
          label: "Yes",
          onClick: () => alert("Click Yes")
        },
        {
          label: "No",
          onClick: () => alert("Click No")
        }
      ]
    });
  };

  return (
    <div>
      <button onClick={submit}>Confirm dialog</button>
    </div>
  );
}

We import the confirmAlert function and call it in the submit method to open the alert dialog with it.

The title property sets the dialog title.

message sets the message content.

buttons add buttons with the given labels and the event handlers for them.

We can also make it display a custom React component as the content:

import React from "react";
import { confirmAlert } from "react-confirm-alert";
import "react-confirm-alert/src/react-confirm-alert.css";

export default function App() {
  const submit = () => {
    confirmAlert({
      customUI: ({ onClose }) => {
        return (
          <div className="custom-ui">
            <h1>Are you sure?</h1>
            <p>You want to delete this file?</p>
            <button onClick={onClose}>No</button>
            <button
              onClick={() => {
                onClose();
              }}
            >
              Yes
            </button>
          </div>
        );
      }
    });
  };

  return (
    <div>
      <button onClick={submit}>Confirm dialog</button>
    </div>
  );
}

We just return a component in the customUI method.

It gets the onClose method from the parameter and call it whenever we want to close the dialog.

Conclusion

We can add modals easily into our React app with the react-modal and react-confirm-alert libraries.

Categories
Vue

Add a Calendar into a Vue App with Vue-FullCalendar

A calendar is something that is hard to create from scratch.

Therefore, there’re many calendar components created for Vue apps.

In this article, we’ll look at how to add a calendar with Vue-FullCalendar.

Installation

We can install the Vue-FullCalendar and its plugins with:

npm install --save @fullcalendar/vue @fullcalendar/daygrid @fullcalendar/interaction

@fullcalendar/vue has the Vue-FullCalendar plugin.

@fullcalendar/daygrid lets us show the day grid in the calendar.

And @fullcalendar/interaction lets us interact with the calendar.

Then we can add a calendar into our Vue component by writing:

<template>
  <FullCalendar :options="calendarOptions" />
</template>

<script>
import FullCalendar from "@fullcalendar/vue";
import dayGridPlugin from "@fullcalendar/daygrid";
import interactionPlugin from "@fullcalendar/interaction";

export default {
  components: {
    FullCalendar,
  },
  data() {
    return {
      calendarOptions: {
        plugins: [dayGridPlugin, interactionPlugin],
        initialView: "dayGridMonth",
      },
    };
  },
};
</script>

The calendarOptions.plugins property lets us add plugins to add the addons we installed.

And the initialView is set to 'dayGridMonth' to let us show a monthly calendar with today’s date as the default date.

To add events to the calendar, we can add the calendarOptions.events property:

<template>
  <FullCalendar :options="calendarOptions" />
</template>

<script>
import FullCalendar from "@fullcalendar/vue";
import dayGridPlugin from "@fullcalendar/daygrid";
import interactionPlugin from "@fullcalendar/interaction";

export default {
  components: {
    FullCalendar,
  },
  data() {
    return {
      calendarOptions: {
        plugins: [dayGridPlugin, interactionPlugin],
        initialView: "dayGridMonth",
        events: [
          { title: "event 1", date: "2020-12-01" },
          { title: "event 2", date: "2020-12-02" },
        ],
      },
    };
  },
};
</script>

title has the event title and date has the event date.

And to listen to events like clicking on dates, we can add more properties.

To listen to date clicks, we add the dateClick property:

<template>
  <FullCalendar :options="calendarOptions" />
</template>

<script>
import FullCalendar from "@fullcalendar/vue";
import dayGridPlugin from "@fullcalendar/daygrid";
import interactionPlugin from "@fullcalendar/interaction";

export default {
  components: {
    FullCalendar,
  },
  data() {
    return {
      calendarOptions: {
        plugins: [dayGridPlugin, interactionPlugin],
        initialView: "dayGridMonth",
        events: [
          { title: "event 1", date: "2020-12-01" },
          { title: "event 2", date: "2020-12-02" },
        ],
        dateClick: this.onDateClick,
      },
    };
  },
  methods: {
    onDateClick(arg) {
      console.log(arg.dateStr);
    },
  },
};
</script>

We set it to the onDateClick event handler to run it when we click on a date.

And we can get the date string of the date that’s clicked with the dateStr property.

We can add other options like show or hide weekends.

To hide weekends, we can set the calendarOptions.weekends property to false :

<template>
  <FullCalendar :options="calendarOptions" />
</template>

<script>
import FullCalendar from "@fullcalendar/vue";
import dayGridPlugin from "@fullcalendar/daygrid";
import interactionPlugin from "@fullcalendar/interaction";

export default {
  components: {
    FullCalendar,
  },
  data() {
    return {
      calendarOptions: {
        plugins: [dayGridPlugin, interactionPlugin],
        initialView: "dayGridMonth",
        events: [
          { title: "event 1", date: "2020-12-01" },
          { title: "event 2", date: "2020-12-02" },
        ],
        weekends: false,
      },
    };
  },
};
</script>

It also comes with some useful utilities like a formatDate function to format dates our way:

<template>
  <FullCalendar :options="calendarOptions" />
</template>

<script>
import FullCalendar from "@fullcalendar/vue";
import dayGridPlugin from "@fullcalendar/daygrid";
import interactionPlugin from "@fullcalendar/interaction";
import { formatDate } from "@fullcalendar/vue";

const str = formatDate(new Date(), {
  month: "long",
  year: "numeric",
  day: "numeric",
});

console.log(str);

export default {
  components: {
    FullCalendar,
  },
  data() {
    return {
      calendarOptions: {
        plugins: [dayGridPlugin, interactionPlugin],
        initialView: "dayGridMonth",
        events: [
          { title: "event 1", date: "2020-12-01" },
          { title: "event 2", date: "2020-12-02" },
        ],
        weekends: false,
      },
    };
  },
};
</script>

Conclusion

We can add the Vue-FullCalendar library to add an event calendar easily into our Vue app.

Categories
Vue

Add a Calendar into a Vue App with Vue-Simple-Calendar

A calendar is something that is hard to create from scratch.

Therefore, there’re many calendar components created for Vue apps.

In this article, we’ll look at how to add a calendar with Vue-Simple-Calendar.

Installation

We can install the plugin by running:

npm i --save vue-simple-calendar

Usage

Once we installed it, we can use the calendar by writing:

<template>
  <div id="app">
    <calendar-view
      :show-date="showDate"
      class="theme-default holiday-us-traditional holiday-us-official"
    >
      <calendar-view-header
        slot="header"
        slot-scope="t"
        :header-props="t.headerProps"
        @input="setShowDate"
      />
    </calendar-view>
  </div>
</template>
<script>
import { CalendarView, CalendarViewHeader } from "vue-simple-calendar";
import "vue-simple-calendar/static/css/default.css";
import "vue-simple-calendar/static/css/holidays-us.css";

export default {
  name: "app",
  data() {
    return { showDate: new Date() };
  },
  components: {
    CalendarView,
    CalendarViewHeader,
  },
  methods: {
    setShowDate(d) {
      this.showDate = d;
    },
  },
};
</script>

We set the show-date prop to set the default date.

Then we populate the header slot to show the render the header with the calendar-view-header component.

This lets us navigate to different months.

We can set the show the displayPeriodUom prop to show the different kinds of periods in the calendar.

We can set it to year to show years and week to show weeks.

The default is month .

We can also set the starting day of the week with the startingDayOfWeek prop.

dateClasses is an object with different date classes for different dates.

We can add more options by adding more props:

<template>
  <div id="app">
    <div class="calendar-controls">
      <div v-if="message" class="notification is-success">{{ message }}</div>

      <div class="box">
        <div class="field">
          <label class="label">Period UOM</label>
          <div class="control">
            <div class="select">
              <select v-model="displayPeriodUom">
                <option>month</option>
                <option>week</option>
                <option>year</option>
              </select>
            </div>
          </div>
        </div>
        <div class="field">
          <label class="label">Period Count</label>
          <div class="control">
            <div class="select">
              <select v-model="displayPeriodCount">
                <option :value="1">1</option>
                <option :value="2">2</option>
                <option :value="3">3</option>
              </select>
            </div>
          </div>
        </div>
        <div class="field">
          <label class="checkbox">
            <input v-model="useTodayIcons" type="checkbox" />
            Use icon for today's period
          </label>
        </div>
        <div class="field">
          <label class="checkbox">
            <input v-model="displayWeekNumbers" type="checkbox" />
            Show week number
          </label>
        </div>
        <div class="field">
          <label class="checkbox">
            <input v-model="showTimes" type="checkbox" />
            Show times
          </label>
        </div>
        <div class="field">
          <label class="label">Themes</label>
          <label class="checkbox">
            <input v-model="useDefaultTheme" type="checkbox" />
            Default
          </label>
        </div>
        <div class="field">
          <label class="checkbox">
            <input v-model="useHolidayTheme" type="checkbox" />
            Holidays
          </label>
        </div>
      </div>

      <div class="box">
        <div class="field">
          <label class="label">Title</label>
          <div class="control">
            <input v-model="newItemTitle" class="input" type="text" />
          </div>
        </div>
        <div class="field">
          <label class="label">Start date</label>
          <div class="control">
            <input v-model="newItemStartDate" class="input" type="date" />
          </div>
        </div>
        <div class="field">
          <label class="label">End date</label>
          <div class="control">
            <input v-model="newItemEndDate" class="input" type="date" />
          </div>
        </div>
        <button class="button is-info" @click="clickTestAddItem">
          Add Item
        </button>
      </div>
    </div>
    <div class="calendar-parent">
      <calendar-view
        :items="items"
        :show-date="showDate"
        :time-format-options="{ hour: 'numeric', minute: '2-digit' }"
        :enable-drag-drop="true"
        :disable-past="disablePast"
        :disable-future="disableFuture"
        :show-times="showTimes"
        :date-classes="myDateClasses"
        :display-period-uom="displayPeriodUom"
        :display-period-count="displayPeriodCount"
        :starting-day-of-week="startingDayOfWeek"
        :period-changed-callback="periodChanged"
        :current-period-label="useTodayIcons ? 'icons' : ''"
        :displayWeekNumbers="displayWeekNumbers"
        :enable-date-selection="true"
        :selection-start="selectionStart"
        :selection-end="selectionEnd"
        @date-selection-start="setSelection"
        @date-selection="setSelection"
        @date-selection-finish="finishSelection"
        @click-date="onClickDay"
        @click-item="onClickItem"
      >
        <calendar-view-header
          slot="header"
          slot-scope="{ headerProps }"
          :header-props="headerProps"
          @input="setShowDate"
        />
      </calendar-view>
    </div>
  </div>
</template>
<script>
import { CalendarView, CalendarViewHeader } from "vue-simple-calendar";
import "vue-simple-calendar/static/css/default.css";
import "vue-simple-calendar/static/css/holidays-us.css";

export default {
  name: "app",
  components: {
    CalendarView,
    CalendarViewHeader,
  },
  data() {
    return {
      showDate: this.thisMonth(1),
      message: "",
      startingDayOfWeek: 0,
      disablePast: false,
      disableFuture: false,
      displayPeriodUom: "month",
      displayPeriodCount: 1,
      displayWeekNumbers: false,
      showTimes: true,
      selectionStart: null,
      selectionEnd: null,
      newItemTitle: "",
      newItemStartDate: "",
      newItemEndDate: "",
      useDefaultTheme: true,
      useHolidayTheme: true,
      useTodayIcons: false,
      items: [
        {
          id: "e0",
          startDate: "2020-01-05",
        },
        {
          id: "e1",
          startDate: new Date(),
        },
        {
          id: "e2",
          startDate: new Date(2020, 11, 1),
          endDate: new Date(2020, 11, 10),
          title: "Multi-day item with a long title and times",
        },
      ],
    };
  },
  computed: {
    userLocale() {
      return this.getDefaultBrowserLocale;
    },
    myDateClasses() {
      const o = {
        ides: new Date().getDate() === 1,
      };
      return o;
    },
  },
  methods: {
    periodChanged() {},
    thisMonth(d, h, m) {
      const t = new Date();
      return new Date(t.getFullYear(), t.getMonth(), d, h || 0, m || 0);
    },
    onClickDay(d) {
      this.selectionStart = null;
      this.selectionEnd = null;
      this.message = `You clicked: ${d.toLocaleDateString()}`;
    },
    onClickItem(e) {
      this.message = `You clicked: ${e.title}`;
    },
    setShowDate(d) {
      this.message = `Changing calendar view to ${d.toLocaleDateString()}`;
      this.showDate = d;
    },
    setSelection(dateRange) {
      this.selectionEnd = dateRange[1];
      this.selectionStart = dateRange[0];
    },
    finishSelection(dateRange) {
      this.setSelection(dateRange);
      this.message = `You selected: ${this.selectionStart.toLocaleDateString()} -${this.selectionEnd.toLocaleDateString()}`;
    },
    clickTestAddItem() {
      this.items.push({
        startDate: this.newItemStartDate,
        endDate: this.newItemEndDate,
        title: this.newItemTitle,
        id: "e" + Math.random().toString(36).substr(2, 10),
      });
      this.message = "You added a calendar item!";
    },
  },
};
</script>

We add items to the items array with the clickTestAddItem method to add calendar events.

We also have select elements to change the period displayed and the number of periods displayed.

Conclusion

We can add the Vue-Simple-Calendar component to add an event calendar with many options in our Vue app.

Categories
Vue

Add a Calendar into a Vue App with Vue2-Simple-Calendar

A calendar is something that is hard to create from scratch.

Therefore, there’re many calendar components created for Vue apps.

In this article, we’ll look at how to add a calendar with Vue2-Simple-Calendar.

Vue2-Simple-Calendar

We can install Vue2-Simple-Calendar by running:

npm install vue2-simple-calendar

with NPM or:

yarn add vue2-simple-calendar

Then we can use it by writing:

main.js

import Vue from "vue";
import App from "./App.vue";
import vueCalendar from "vue2-simple-calendar";
import "./assets/calendar.css";

Vue.use(vueCalendar, {});
Vue.config.productionTip = false;

new Vue({
  render: (h) => h(App)
}).$mount("#app");

App.vue

<template>
  <div id="app">
    <vue-calendar
      :show-limit="3"
      :events="events"
      :disable="disabledDays"
      :highlight="highlightDays"
      @show-all="showAll"
      @day-clicked="dayClicked"
      @event-clicked="eventClicked"
      @month-changed="monthChanged"
    ></vue-calendar>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      events: [
        {
          title: "event",
          start: new Date(),
          end: new Date(),
        },
      ],
      disabledDays: {
        to: new Date(2020, 9, 5),
        from: new Date(2020, 11, 26),
      },
      highlightDays: {
        days: [6, 0],
      },
    };
  },
  methods: {
    showAll(events) {
      // Do something...
    },
    dayClicked(day) {
      // Do something...
    },
    eventClicked(event) {
      // Do something...
    },
    monthChanged(start, end) {
      // Do something...
    },
  },
  created() {
    this.$calendar.eventBus.$on("show-all", (events) => this.showAll(events));
    this.$calendar.eventBus.$on("day-clicked", (day) => this.dayClicked(day));
    this.$calendar.eventBus.$on("event-clicked", (event) => console.log(event));
    this.$calendar.eventBus.$on("month-changed", (start, end) =>
      console.log(start, end)
    );
  },
};
</script>

/assets/calendar.css

.vue-calendar {
  display: grid;
  grid-template-rows: 10% 90%;
  background: #fff;
  margin: 0 auto;
}
.calendar-header {
  align-items: center;
}
.header-left,
.header-right {
  flex: 1;
}
.header-center {
  flex: 3;
  text-align: center;
}
.title {
  margin: 0 5px;
}
.next-month,
.prev-month {
  cursor: pointer;
}
.calendar-body {
  display: grid;
  grid-template-rows: 5% 95%;
}
.days-header {
  display: grid;
  grid-auto-columns: 14.25%;
  grid-template-areas: "a a a a a a a";
  border-top: 1px solid #e0e0e0;
  border-left: 1px solid #e0e0e0;
  border-bottom: 1px solid #e0e0e0;
}
.days-body {
  display: grid;
  grid-template-rows: auto;
}
.day-number {
  text-align: right;
  margin-right: 10px;
}
.day-label {
  text-align: center;
  border-right: 1px solid #e0e0e0;
}
.week-row {
  display: grid;
  grid-template-areas: "a a a a a a a";
  grid-row-gap: 5px;
  grid-auto-columns: 14.25%;
  border-left: 1px solid #e0e0e0;
}
.week-day {
  padding: 4px;
  border-right: 1px solid #e0e0e0;
  border-bottom: 1px solid #e0e0e0;
}
.week-day.disabled {
  background-color: #f5f5f5;
}
.week-day.not-current > .day-number {
  color: #c3c3c3;
}
.week-day.today > .day-number {
  font-weight: 700;
  color: red;
}
.events {
  font-size: 12px;
  cursor: pointer;
  padding: 0 0 0 4px;
}
.events .event {
  height: 18px;
  line-height: 18px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  margin: 0 4px 2px 0;
  color: rgba(0, 0, 0, 0.87);
  background-color: #d4dcec;
}
.events .more-link {
  color: rgba(0, 0, 0, 0.38);
}

We add the grid layout with the days-header and the week-row classes.

In main.js , we add the VueCalendar plugin so we can use it our components.

We need to import the calendar.css to apply the styles from the CSS styles.

In App.vue , we add the vue-calendar component to add the calendar.

show-limit has the max number of events shown in a day.

events has an array of events.

disable has days that we want to disable.

show-all event is emitted when the show more link is clicked.

day-clicked is emitted when a day is clicked.

event-clicked is emitted when an event is clicked.

month-changed is emitted when the month changed.

Conclusion

The Vue2-Simple-Calendar lets us add an event calendar easily into our Vue app.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Loading Indicator

Quasar is a popular Vue UI library for developing good looking Vue apps.

In this article, we’ll take a look at how to create Vue apps with the Quasar UI library.

Loading Indicator

We can add a loading indicator with the $q.loading object:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md"></div>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {},
        beforeMount() {
          this.$q.loading.show({
            delay: 400
          });
          setTimeout(() => {
            this.$q.loading.hide();
          }, 3000);
        }
      });
    </script>
  </body>
</html>

We call the $q.loading.show method with the delay property to delay the loading indicator’s display.

The number is in milliseconds.

Then we hide it with the $q.loading.hide method.

We can add a message with the message property:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md"></div>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {},
        beforeMount() {
          this.$q.loading.show({
            delay: 400,
            message:
              'Some important <b>process</b> is in progress.<br/><span class="text-primary">Hang on...</span>'
          });
          setTimeout(() => {
            this.$q.loading.hide();
          }, 3000);
        }
      });
    </script>
  </body>
</html>

We can set it to HTML.

We can add the sanitize property to the object to escape the HTML code.

We can add more customizations with more properties:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md"></div>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {},
        beforeMount() {
          this.$q.loading.show({
            spinner: Quasar.QSpinnerFacebook,
            spinnerColor: "yellow",
            spinnerSize: 140,
            backgroundColor: "purple",
            message: "Some important process is in progress. Hang on...",
            messageColor: "black"
          });
          setTimeout(() => {
            this.$q.loading.hide();
          }, 3000);
        }
      });
    </script>
  </body>
</html>

spinner has the icon for the loading spinner,

spinnerColor sets the spinner color.

spinnerSize sets the spinner size.

backgroundColor sets the background color of the overlay.

messageColor sets the color of the message.

Loading Bar

We can add a loading bar with the $q.loadingBar object.

For instance, we can write:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md"></div>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {},
        beforeMount() {
          this.$q.loadingBar.start();

          setTimeout(() => {
            this.$q.loadingBar.stop();
          }, 3000);
        }
      });
    </script>
  </body>
</html>

We call start to show it and stop to stop it.

We can also call this.$q.loadingBar.increment(value) to change the progress value.

Also, we can change the options with the LoadingBar.setDefaults method:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <div class="q-pa-md"></div>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {},
        beforeMount() {
          Quasar.LoadingBar.setDefaults({
            color: "purple",
            size: "15px",
            position: "bottom"
          });
          this.$q.loadingBar.start();

          setTimeout(() => {
            this.$q.loadingBar.stop();
          }, 3000);
        }
      });
    </script>
  </body>
</html>

We set the color , size , and position to set those styles.

Conclusion

We can add a loading indicator with various styles into our Vue app with Quasar’s loading bar plugin.