Categories
Quasar

Developing Vue Apps with the Quasar Library — Responsive Container

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.

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.

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 *