Categories
Quasar

Developing Vue Apps with the Quasar Library — Menu Target Element and Observing Resize

Spread the love

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.

Menu Target Element

We can change the menu’s target element with q-menu ‘s target 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">
          <div class="row justify-center">
            <div class="row items-center q-gutter-x-sm">
              <q-radio
                v-model="targetEl"
                :val="false"
                label="false (no target)"
              >
              </q-radio>
              <q-radio
                v-model="targetEl"
                :val="true"
                label="true (original parent)"
              >
              </q-radio>
              <q-radio
                v-model="targetEl"
                val="#target-img-1"
                label="#target-img-1"
              >
              </q-radio>
            </div>
          </div>
          <div class="row justify-center">
            <q-img
              src="https://cdn.quasar.dev/img/material.png"
              id="target-img-1"
              style="height: 100px;"
            >
              <div
                class="absolute-bottom-right"
                style="border-top-left-radius: 5px;"
              >
                #target-img-1
              </div>
            </q-img>
            <q-img
              src="https://cdn.quasar.dev/img/parallax2.jpg"
              id="target-img-2"
              style="height: 100px;"
            >
              <div
                class="absolute-bottom-right"
                style="border-top-left-radius: 5px;"
              >
                #target-img-2
              </div>
            </q-img>
            <q-img
              src="https://cdn.quasar.dev/img/blueish.jpg"
              style="height: 100px;"
            >
              <div
                class="absolute-bottom-right"
                style="border-top-left-radius: 5px;"
              >
                Original parent
              </div>
              <q-menu touch-position :target="targetEl">
                <q-list>
                  <q-item v-for="n in 5" :key="n" v-close-popup clickable>
                    <q-item-section>Label</q-item-section>
                  </q-item>
                </q-list>
              </q-menu>
            </q-img>
          </div>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          targetEl: "#target-img-1"
        }
      });
    </script>
  </body>
</html>

We set the targetEl reactive property to the selector for the image we want to target.

Also, we can set it to false to disable the menu for all elements.

Or we can set the target to true to set the target element to the original one set in data .

Resize Observer

We can watch the size of an element with the q-resize-observer component.

For example, we can use it by writing:

<!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">
          <div
            style="width: 80vw; height: 50vh;"
            class="container bg-amber rounded-borders glossy"
          >
            <q-resize-observer @resize="onResize"></q-resize-observer>
          </div>

          <div class="q-gutter-sm">
            Reported:
            <q-badge>width: {{ report.width }}</q-badge>
            <q-badge>height: {{ report.height }}</q-badge>
          </div>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          report: {}
        },
        methods: {
          onResize(size) {
            this.report = size;
          }
        }
      });
    </script>
  </body>
</html>

We add the q-resize-observer inside the element that we want to watch the size to watch its size when resizing.

We listen to the resize event to get the size.

The size parameter of the event handler has the width and height property to get the size.

Conclusion

We can set the target element for our menu and watch element size in our Vue app with Quasar.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *