Categories
Quasar

Developing Vue Apps with the Quasar Library — Responsive Container

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.

Responsive Container

We can add a responsive container into our Vue app with the q-responsive component.

We set the ratio prop to set the aspect ratio that the container maintains when it’s resized:

<!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"
      >
        <q-responsive :ratio="16/9">
          <div class="rounded-borders bg-primary text-white flex flex-center">
            Ratio 16:9
          </div>
        </q-responsive>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We can add a card inside the q-responsive 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"
    />
  </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"
      >
        <q-responsive :ratio="16/9">
          <q-card class="column">
            <q-img class="col" src="https://cdn.quasar.dev/img/parallax2.jpg" />

            <q-card-section>
              <div>Ratio 16:9</div>
            </q-card-section>
          </q-card>
        </q-responsive>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We can also wrap q-responsive around a q-card-section 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"
    />
  </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"
      >
        <q-card flat bordered class="col">
          <q-item>
            <q-item-section avatar>
              <q-avatar>
                <img src="https://cdn.quasar.dev/img/avatar.png" />
              </q-avatar>
            </q-item-section>

            <q-item-section>
              <q-item-label>Title</q-item-label>
              <q-item-label caption>
                Subhead
              </q-item-label>
            </q-item-section>
          </q-item>

          <q-separator></q-separator>

          <q-responsive :ratio="16/9">
            <q-card-section
              class="border-radius-inherit flex flex-center bg-grey-1"
            >
              <div>16:9</div>
            </q-card-section>
          </q-responsive>
        </q-card>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We can wrap the q-responsive component around a q-table to resize the aspect ratio:

<!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"
      >
        <q-responsive :ratio="16/9">
          <q-table
            class="my-sticky-table"
            virtual-scroll
            :pagination.sync="pagination"
            :rows-per-page-options="[0]"
            :virtual-scroll-sticky-size-start="48"
            row-key="index"
            title="Table"
            :data="data"
            :columns="columns"
          >
          </q-table>
        </q-responsive>
      </q-layout>
    </div>
    <script>
      const seed = [
        {
          name: "Frozen Yogurt",
          calories: 159,
          fat: 6.0,
          carbs: 24,
          protein: 4.0
        },
        {
          name: "Ice cream sandwich",
          calories: 237,
          fat: 9.0,
          carbs: 37,
          protein: 4.3
        },
        {
          name: "Honeycomb",
          calories: 408,
          fat: 2.2,
          carbs: 87,
          protein: 6.5
        },
        {
          name: "Donut",
          calories: 452,
          fat: 25.0,
          carbs: 51,
          protein: 4.9
        },
        {
          name: "KitKat",
          calories: 518,
          fat: 26.0,
          carbs: 65,
          protein: 7
        }
      ];

      let data = [];
      for (let i = 0; i < 100; i++) {
        data = [...data, ...seed];
      }
      data = data.map((d, index) => ({ ...d, index }));

      Object.freeze(data);

      new Vue({
        el: "#q-app",
        data: {
          data,

          pagination: {
            rowsPerPage: 0
          },

columns: [
            {
              name: "index",
              label: "#",
              field: "index"
            },
            {
              name: "name",
              required: true,
              label: "Dessert (100g serving)",
              align: "left",
              field: (row) => row.name,
              format: (val) => `${val}`,
              sortable: true
            },
            {
              name: "calories",
              align: "center",
              label: "Calories",
              field: "calories",
              sortable: true
            },
            { name: "fat", label: "Fat (g)", field: "fat", sortable: true },
            { name: "carbs", label: "Carbs (g)", field: "carbs" },
            { name: "protein", label: "Protein (g)", field: "protein" }
          ]
        }
      });
    </script>
  </body>
</html>

Conclusion

We can use Quasar’s q-responsive component to add a responsive container that maintains the aspect ratio when it’s resized.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Rating Control 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.

Rating Control Color

We can set the color of each icon with the color-selected 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"
      >
        <q-rating
          v-model="ratingModel"
          color="grey"
          size="3.5em"
          :color-selected="ratingColors"
        >
        </q-rating>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          ratingModel: 4.5,
          ratingColors: [
            "light-green-3",
            "light-green-6",
            "green",
            "green-9",
            "green-10"
          ]
        }
      });
    </script>
  </body>
</html>

We can set a different icon for half scores with he icon-half 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"
    />
  </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"
      >
        <q-rating
          v-model="ratingModel"
          size="3.5em"
          color="yellow"
          icon="star_border"
          icon-selected="star"
          icon-half="star_half"
        >
        </q-rating>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          ratingModel: 4.5
        }
      });
    </script>
  </body>
</html>

We can disable dimming for unselected icons with the no-dimming 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"
      >
        <q-rating
          v-model="ratingModel"
          size="3.5em"
          color="yellow"
          icon="star_border"
          icon-selected="star"
          icon-half="star_half"
          no-dimming
        >
        </q-rating>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          ratingModel: 3.5
        }
      });
    </script>
  </body>
</html>

Rating Tooltip

We can set the tooltip for each rating by populating the slots for the tooltip content:

<!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"
      >
        <q-rating v-model="ratingModel" size="3.5em" :max="3">
          <template v-slot:tip-1>
            <q-tooltip>Not bad</q-tooltip>
          </template>
          <template v-slot:tip-2>
            <q-tooltip>Good</q-tooltip>
          </template>
          <template v-slot:tip-3>
            <q-tooltip>Very good</q-tooltip>
          </template>
        </q-rating>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          ratingModel: 2
        }
      });
    </script>
  </body>
</html>

tip-1’s content is shown when we hover over the left star. tip-2 ‘s content is show when we hover over the 2nd to left star, etc.

Readonly and Disable

We can disable rating selection with the readonly or disable props:

<!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"
      >
        <q-rating v-model="ratingModel" size="3.5em" :max="3" readonly>
        </q-rating>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          ratingModel: 2
        }
      });
    </script>
  </body>
</html>

Conclusion

We can add a rating component with various options into our Vue app with Quasar.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Rating Control

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.

Rating Control

We can add a rating control into our Vue app with the Quasarq-rating component.

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">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <q-rating v-model="ratingModel" size="1.5em" icon="thumb_up">
        </q-rating>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          ratingModel: 4.5
        }
      });
    </script>
  </body>
</html>

We bind the value to display to the ratingModel reactive property with v-model

size sets the size of the icon.

icon sets the name of the icon.

We can set the max rating score with the max 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"
      >
        <q-rating v-model="ratingModel" size="2em" :max="10" color="primary">
        </q-rating>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          ratingModel: 4.5
        }
      });
    </script>
  </body>
</html>

The icon for the rating display can also be an image:

<!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"
      >
        <q-rating
          v-model="ratingModel"
          size="2em"
          color="primary"
          icon="img:https://cdn.quasar.dev/logo/svg/quasar-logo.svg"
        >
        </q-rating>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          ratingModel: 4.5
        }
      });
    </script>
  </body>
</html>

We can set an icon to display when the rating icon is selected with the icon-selected 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"
      >
        <q-rating
          v-model="ratingModel"
          size="3.5em"
          color="green-5"
          icon="star_border"
          icon-selected="star"
        >
        </q-rating>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          ratingModel: 4.5
        }
      });
    </script>
  </body>
</html>

We can also set each icon to a different one with the icon 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"
      >
        <q-rating
          v-model="ratingModel"
          size="3.5em"
          color="green-5"
          :icon="icons"
        >
        </q-rating>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          ratingModel: 4.5,
          icons: [
            "sentiment_very_dissatisfied",
            "sentiment_dissatisfied",
            "sentiment_satisfied",
            "sentiment_very_satisfied"
          ]
        }
      });
    </script>
  </body>
</html>

We set icon to an array of icon names.

Conclusion

We can add a rating control into our Vue app with Quasar.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Popup Proxy and Pull to Refresh

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.

Popup Proxy

We can use Quasar’s q-popup-proxy component to add a popup that’s triggered by clicking a button.

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">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <q-btn push color="primary" label="button">
            <q-popup-proxy>
              <q-banner>
                <template v-slot:avatar>
                  <q-icon name="signal_wifi_off" color="primary" />
                </template>
                You are offline
              </q-banner>
            </q-popup-proxy>
          </q-btn>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We add it inside the button to make the popup display when we click the button.

The popup content is inside the q-popup-proxy ‘s default slot.

We can make the popup display when we right-click with the context-menu 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-btn push color="primary" label="button">
            <q-popup-proxy context-menu>
              <q-banner>
                <template v-slot:avatar>
                  <q-icon name="signal_wifi_off" color="primary" />
                </template>
                You are offline
              </q-banner>
            </q-popup-proxy>
          </q-btn>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We can also make the popup trigger when we click on an icon that we have in the input with:

<!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-input filled v-model="input" mask="date" :rules="['date']">
            <template v-slot:append>
              <q-icon name="event" class="cursor-pointer">
                <q-popup-proxy :breakpoint="600">
                  <q-date v-model="input"></q-date>
                </q-popup-proxy>
              </q-icon>
            </template>
          </q-input>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          input: undefined
        }
      });
    </script>
  </body>
</html>

Pull to Refresh

We can add pull to refresh functionality with the q-pull-to-refresh component.

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">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <div class="q-pa-md scroll" style="height: 300px;">
            <q-pull-to-refresh @refresh="refresh">
              <div v-for="n in num" :key="n" class="q-mb-sm">
                {{num - n}} - Lorem ipsum
              </div>
            </q-pull-to-refresh>
          </div>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          num: 50
        },
        methods: {
          refresh(done) {
            setTimeout(() => {
              this.num += 50;
              done();
            }, 1000);
          }
        }
      });
    </script>
  </body>
</html>

We have the items that we can pull to refresh inside tyhe q-pull-to-refresh component.

In the refresh handler, we call done when we’re done refreshing the content.

Conclusion

We can add popups and pull to refresh into our Vue app with Quasar.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Popup Proxy and Pull to Refresh

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.

Popup Proxy

We can use Quasar’s q-popup-proxy component to add a popup that’s triggered by clicking a button.

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">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <q-btn push color="primary" label="button">
            <q-popup-proxy>
              <q-banner>
                <template v-slot:avatar>
                  <q-icon name="signal_wifi_off" color="primary" />
                </template>
                You are offline
              </q-banner>
            </q-popup-proxy>
          </q-btn>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We add it inside the button to make the popup display when we click the button.

The popup content is inside the q-popup-proxy ‘s default slot.

We can make the popup display when we right-click with the context-menu 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-btn push color="primary" label="button">
            <q-popup-proxy context-menu>
              <q-banner>
                <template v-slot:avatar>
                  <q-icon name="signal_wifi_off" color="primary" />
                </template>
                You are offline
              </q-banner>
            </q-popup-proxy>
          </q-btn>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We can also make the popup trigger when we click on an icon that we have in the input with:

<!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-input filled v-model="input" mask="date" :rules="['date']">
            <template v-slot:append>
              <q-icon name="event" class="cursor-pointer">
                <q-popup-proxy :breakpoint="600">
                  <q-date v-model="input"></q-date>
                </q-popup-proxy>
              </q-icon>
            </template>
          </q-input>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          input: undefined
        }
      });
    </script>
  </body>
</html>

Pull to Refresh

We can add pull to refresh functionality with the q-pull-to-refresh component.

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">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div class="q-pa-md">
          <div class="q-pa-md scroll" style="height: 300px;">
            <q-pull-to-refresh @refresh="refresh">
              <div v-for="n in num" :key="n" class="q-mb-sm">
                {{num - n}} - Lorem ipsum
              </div>
            </q-pull-to-refresh>
          </div>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          num: 50
        },
        methods: {
          refresh(done) {
            setTimeout(() => {
              this.num += 50;
              done();
            }, 1000);
          }
        }
      });
    </script>
  </body>
</html>

We have the items that we can pull to refresh inside tyhe q-pull-to-refresh component.

In the refresh handler, we call done when we’re done refreshing the content.

Conclusion

We can add popups and pull to refresh into our Vue app with Quasar.