Categories
Quasar

Developing Vue Apps with the Quasar Library — Lists

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.

Lists

Quasar comes with a list component that we can use in a Vue app.

We can add a list with the q-list component:

<!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"
    />
    <style>
      .example-item {
        height: 200px;
        width: 200px;
      }
    </style>
  </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">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <q-list bordered separator>
            <q-item clickable v-ripple>
              <q-item-section>Single line item</q-item-section>
            </q-item>

            <q-item clickable v-ripple>
              <q-item-section>
                <q-item-label>Orange</q-item-label>
                <q-item-label caption>Caption</q-item-label>
              </q-item-section>
            </q-item>

            <q-item clickable v-ripple>
              <q-item-section>
                <q-item-label overline>Apple</q-item-label>
                <q-item-label>Item with caption</q-item-label>
              </q-item-section>
            </q-item>
          </q-list>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app"
      });
    </script>
  </body>
</html>

The bordered prop adds a border around the list.

separator adds a separator between the items.

q-item lets us add items into the list.

clickable makes the item clickable.

v-ripple adds a ripple effect when we click on the item.

q-item-label is a container for the text in the item.

We can also add a list on a dark background with a few classes and the dark prop:

<!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"
    />
    <style>
      .example-item {
        height: 200px;
        width: 200px;
      }
    </style>
  </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">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md bg-grey-10 text-white">
          <q-list dark bordered separator>
            <q-item clickable v-ripple>
              <q-item-section>Single line item</q-item-section>
            </q-item>

            <q-item clickable v-ripple>
              <q-item-section>
                <q-item-label>Orange</q-item-label>
                <q-item-label caption>Caption</q-item-label>
              </q-item-section>
            </q-item>

            <q-item clickable v-ripple>
              <q-item-section>
                <q-item-label overline>Apple</q-item-label>
                <q-item-label>Item with caption</q-item-label>
              </q-item-section>
            </q-item>
          </q-list>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app"
      });
    </script>
  </body>
</html>

bg-grey-10 makes the background dark. text-white makes the text white.

We can make a dense list with the dense prop:

<!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"
    />
    <style>
      .example-item {
        height: 200px;
        width: 200px;
      }
    </style>
  </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">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <q-list dense bordered padding class="rounded-borders">
            <q-item clickable v-ripple>
              <q-item-section>
                Apple
              </q-item-section>
            </q-item>

            <q-item clickable v-ripple>
              <q-item-section>
                Orange
              </q-item-section>
            </q-item>

            <q-item clickable v-ripple>
              <q-item-section>
                Grape
              </q-item-section>
            </q-item>
          </q-list>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app"
      });
    </script>
  </body>
</html>

Conclusion

We can add lists into our Vue with the Quasar library.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Linear Progress Bar

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.

Linear Progress Bar

We can add a linear progress bar into our Vue app with Quasar’s q-linear-progress component.

To add it, we 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">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <q-linear-progress
            indeterminate
            rounded
            track-color="orange"
            color="purple"
            class="q-mt-sm"
          ></q-linear-progress>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

The track-color is the background color.

color is the progress bar’s color.

indeterminate makes the bar move in a loop.

rounded makes the bar rounded.

The reverse prop reverses the direction of the progress bar movement:

<!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">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <q-linear-progress
            indeterminate
            rounded
            reverse
            track-color="orange"
            color="purple"
            class="q-mt-sm"
          ></q-linear-progress>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

The height of the bar can be changed with the size prop:

<!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">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <q-linear-progress
            indeterminate
            rounded
            size="25px"
            track-color="orange"
            color="purple"
            class="q-mt-sm"
          ></q-linear-progress>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          value: 9
        }
      });
    </script>
  </body>
</html>

We can also change the size to a standard size:

<!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"
    />
    <style>
      .example-item {
        height: 200px;
        width: 200px;
      }
    </style>
  </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">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <q-linear-progress
            indeterminate
            rounded
            size="xl"
            track-color="orange"
            color="purple"
            class="q-mt-sm"
          ></q-linear-progress>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          value: 9
        }
      });
    </script>
  </body>
</html>

Other possible values include ‘xs’, ‘sm’, ‘md’, and ‘lg’ .

We can set the value prop to display the progress value we want and also add a label by populating the default slot:

<!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">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <q-linear-progress size="25px" :value="progress" color="accent">
            <div class="absolute-full flex flex-center">
              <q-badge color="white" text-color="accent" :label="progressLabel">
              </q-badge>
            </div>
          </q-linear-progress>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          progress: 0.3
        },

        computed: {
          progressLabel() {
            return (this.progress * 100).toFixed(2) + "%";
          }
        }
      });
    </script>
  </body>
</html>

Conclusion

We can add a linear progress bar into our Vue app with the q-linear-progress component.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Knob

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.

Knob

We can add the q-knob component to show a circular loading indicator.

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"
    />
    <style>
      .example-item {
        height: 200px;
        width: 200px;
      }
    </style>
  </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">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <q-knob
            v-model="value"
            size="90px"
            :thickness="0.2"
            color="purple-3"
            center-color="purple"
            track-color="purple-1"
            class="q-ma-md"
          >
          </q-knob>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          value: 75
        }
      });
    </script>
  </body>
</html>

to add the loading indicator.

size is the diameter.

color has the color of the ring that’s not filled.

center-color has the center part’s color.

track-color has the outer ring’s color.

thickness has the thickness of the ring.

We can populate the default slot to add content inside the loading indicator:

<!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"
    />
    <style>
      .example-item {
        height: 200px;
        width: 200px;
      }
    </style>
  </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">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <q-knob
            show-value
            font-size="16px"
            class="text-red q-ma-md"
            v-model="value"
            size="60px"
            :thickness="0.05"
            color="red"
            track-color="grey-3"
          >
            <q-icon name="volume_up" class="q-mr-xs"></q-icon>
            {{ value }}
          </q-knob>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          value: 75
        }
      });
    </script>
  </body>
</html>

We can also add the min and max props to add min and max values for the loading indicator.

The ring’s perimeter is display proportional to the min and max values:

<!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"
    />
    <style>
      .example-item {
        height: 200px;
        width: 200px;
      }
    </style>
  </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">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <q-knob
            show-value
            font-size="16px"
            class="text-red q-ma-md"
            v-model="value"
            size="60px"
            :thickness="0.05"
            color="red"
            track-color="grey-3"
            :min="5"
            :max="10"
          >
            <q-icon name="volume_up" class="q-mr-xs"></q-icon>
            {{ value }}
          </q-knob>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          value: 8
        }
      });
    </script>
  </body>
</html>

We can add the step prop to make the knob’s ring snap to the nearest multiple of the step value:

<!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"
    />
    <style>
      .example-item {
        height: 200px;
        width: 200px;
      }
    </style>
  </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">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <q-knob
            show-value
            font-size="16px"
            class="text-red q-ma-md"
            v-model="value"
            size="60px"
            :thickness="0.05"
            color="red"
            track-color="grey-3"
            :min="5"
            :max="10"
            :step="2"
          >
            <q-icon name="volume_up" class="q-mr-xs"></q-icon>
            {{ value }}
          </q-knob>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          value: 9
        }
      });
    </script>
  </body>
</html>

Conclusion

We can add a knob component with Quasar to add a circular loading indicator into our Vue app.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Loading Indicators and Intersections

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 inside a card with the q-inner-loading component.

To add it, we 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">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <q-card class="bg-grey-3 relative-position card-example">
            <q-card-section class="q-pb-none">
              <div class="text-h6">Lorem Ipsum</div>
            </q-card-section>

            <q-card-section>
              <transition
                appear
                enter-active-class="animated fadeIn"
                leave-active-class="animated fadeOut"
              >
                <div v-show="showData">
                  Lorem ipsum dolor sit amet
                </div>
              </transition>
            </q-card-section>

            <q-inner-loading :showing="visible">
              <q-spinner-gears size="50px" color="primary" />
            </q-inner-loading>
          </q-card>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          visible: false,
          showData: false
        },
        methods: {
          showTextLoading() {
            this.visible = true;
            this.showData = false;
            setTimeout(() => {
              this.visible = false;
              this.showData = true;
            }, 3000);
          }
        },
        beforeMount() {
          this.showTextLoading();
        }
      });
    </script>
  </body>
</html>

The showing prop lets us control when to show the indicator.

Intersection

We can use the q-intersection component as a scroll container.

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"
    />
    <style>
      .example-item {
        height: 200px;
        width: 200px;
      }
    </style>
  </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">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <div class="row justify-center q-gutter-sm">
            <q-intersection
              v-for="index in 60"
              :key="index"
              class="example-item"
            >
              <q-card class="q-ma-sm">
                <img src="https://cdn.quasar.dev/img/mountains.jpg" />

                <q-card-section>
                  <div class="text-h6">Card #{{ index }}</div>
                </q-card-section>
              </q-card>
            </q-intersection>
          </div>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We add the q-card inside to add cards to show items.

We can add the transition prop to add the transition effects:

<!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"
    />
    <style>
      .example-item {
        height: 200px;
        width: 200px;
      }
    </style>
  </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">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <div class="row justify-center q-gutter-sm">
            <q-intersection
              transition="scale"
              v-for="index in 60"
              :key="index"
              class="example-item"
            >
              <q-card class="q-ma-sm">
                <img src="https://cdn.quasar.dev/img/mountains.jpg" />

                <q-card-section>
                  <div class="text-h6">Card #{{ index }}</div>
                </q-card-section>
              </q-card>
            </q-intersection>
          </div>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

Conclusion

We can add loading indicators and watch intersections with Quasar.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Infinite Scroll Options

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.

Reverse Infinite Scroll

We can reverse the direction of the infinite scroll with the reverse prop:

<!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">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <q-infinite-scroll @load="onLoad" reverse>
            <template slot="loading">
              <div class="row justify-center q-my-md">
                <q-spinner color="primary" name="dots" size="40px" />
              </div>
            </template>

            <div
              v-for="(item, index) in items"
              :key="index"
              class="caption q-py-sm"
            >
              <q-badge class="shadow-1">
                {{ items.length - index }}
              </q-badge>
              Lorem ipsum
            </div>
          </q-infinite-scroll>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          items: [{}, {}, {}, {}, {}, {}, {}]
        },
        methods: {
          onLoad(index, done) {
            setTimeout(() => {
              if (this.items) {
                this.items.push({}, {}, {}, {}, {}, {}, {});
                done();
              }
            }, 2000);
          }
        }
      });
    </script>
  </body>
</html>

We can also add an infinite scroll container inside menus:

<!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">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <q-btn color="brown" label="Menu">
            <q-menu
              anchor="bottom middle"
              self="top middle"
              :offset="[ 0, 8 ]"
              @show="scrollTarget = $refs.scrollTargetRef"
            >
              <q-item-label header>
                Notifications
              </q-item-label>
              <q-list
                ref="scrollTargetRef"
                class="scroll"
                style="max-height: 230px;"
              >
                <q-infinite-scroll
                  @load="onLoad"
                  :offset="250"
                  :scroll-target="scrollTarget"
                >
                  <q-item v-for="(item, index) in items" :key="index">
                    <q-item-section>
                      {{ index + 1 }}. Lorem ipsum
                    </q-item-section>
                  </q-item>

                  <template v-slot:loading>
                    <div class="text-center q-my-md">
                      <q-spinner-dots
                        color="primary"
                        size="40px"
                      ></q-spinner-dots>
                    </div>
                  </template>
                </q-infinite-scroll>
              </q-list>
            </q-menu>
          </q-btn>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          scrollTarget: undefined,
          items: [{}, {}, {}, {}, {}, {}, {}]
        },
        methods: {
          onLoad(index, done) {
            if (index > 1) {
              setTimeout(() => {
                if (this.items) {
                  this.items.push({}, {}, {}, {}, {}, {}, {});
                  done();
                }
              }, 2000);
            } else {
              setTimeout(() => {
                done();
              }, 200);
            }
          }
        }
      });
    </script>
  </body>
</html>

We add the q-infinite-scroll component into the q-list and the q-list is inside the q-menu .

Conclusion

We can add an infinite scrolling container into our Vue app with Quasar.