Categories
JavaScript

Introducing the JavaScript Window Object -Design Mode and More

The window object is a global object that has the properties pertaining to the current DOM document, which is the things that are in the tab of a browser. The document property of the window object has the DOM document and associated nodes and methods that we can use to manipulate the DOM nodes and listen to events for each node. Since the window object is global, it’s available in every part of the application. When a variable is declared without the var , let or const keywords, they’re automatically attached to the window object, making them available to every part of your web app. This is only applicable when strict mode is disabled. If it’s enabled, then declaring variables without var , let , or const will be stopped an error since it’s not a good idea to let us declare global variables accidentally. The window object has many properties. They include constructors, value properties and methods. There’re methods to manipulate the current browser tab like opening and closing new popup windows, etc.

In a tabbed browser, each tab has its own window object, so the window object always represent the state of the currently opened tab in which the code is running. However, some properties still apply to all tabs of the browser like the resizeTo method and the innerHeight and innerWidth properties.

Note that we don’t need to reference the window object directly for invoking methods and object properties. For example, if we want to use the window.Image constructor, we can just write new Image() . In this article, we continue to look at what’s in the window object. In the previous sections, we looked at the constructors and some of the properties of the window object, including using the customElements to build a Web Component, and the crypto object to do cryptography on the client using symmetric and asymmetric encryption algorithms. In this part, we will continue from Part 11 and look at more properties of the window.document object, including the defaultView , designMode , dir, domain, and lastModified properties.

window.document.defaultView

The defaultView property is a read only property that returns the window object associated with the current document, or null if it’s not available. For example, if we run the following code to log the document.defaultView object:

console.log(document.defaultView);

We should get something like:

alert: ƒ alert()  
applicationCache: ApplicationCache {status: 0, oncached: null, onchecking: null, ondownloading: null, onerror: null, …}  
atob: ƒ atob()  
blur: ƒ ()  
btoa: ƒ btoa()  
caches: CacheStorage {}  
cancelAnimationFrame: ƒ cancelAnimationFrame()  
cancelIdleCallback: ƒ cancelIdleCallback()  
captureEvents: ƒ captureEvents()  
chrome: {loadTimes: ƒ, csi: ƒ}  
clearInterval: ƒ clearInterval()  
clearTimeout: ƒ clearTimeout()  
clientInformation: Navigator {vendorSub: "", productSub: "20030107", vendor: "Google Inc.", maxTouchPoints: 0, hardwareConcurrency: 4, …}  
close: ƒ ()  
closed: false  
confirm: ƒ confirm()  
createImageBitmap: ƒ createImageBitmap()  
crypto: Crypto {subtle: SubtleCrypto}  
customElements: CustomElementRegistry {}  
...

where the list of properties goes on for much longer than the abridged output above.

window.document.designMode

The designMode property controls whether is the entire document is editable. We can either set it to 'on' or 'off' . In Internet Explorer 6 to 10, the values are capitalized. Earlier versions of Chrome and Internet Explorer defaults to 'inherit' , but the 'inherit' value is no longer supported. Starting with Chrome 43, the default is 'off' . For example, if we have the following code HTML code:

<div>  
  <p>  
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus non pharetra dolor. Fusce gravida enim nec lectus rutrum bibendum. Duis mattis nisl tristique, tincidunt mauris ac, ornare lectus. Praesent non massa tristique magna placerat sagittis at consectetur libero. Maecenas varius urna in odio faucibus, at elementum lorem tempor. Duis metus enim, finibus sed ante at, mollis posuere elit. Maecenas elementum tristique vulputate. Curabitur eleifend vehicula congue. Nam bibendum augue sit amet dui egestas, quis ultrices ipsum blandit. Nulla arcu tortor, fringilla eu luctus ac, porta nec sem.  
  </p>

<p>  
    Sed mauris odio, cursus quis lacus at, vulputate varius nisl. Praesent eget accumsan mauris. In gravida magna non ante ultrices, vel egestas enim pulvinar. Duis pulvinar volutpat ex. Donec ac lectus non sapien gravida egestas nec non sapien. Aenean eu vehicula dui, eu aliquam leo. Vivamus viverra tempor lacus, nec venenatis quam blandit a. Mauris viverra diam quis euismod elementum. Aenean quis sapien sit amet metus tempus auctor et vel elit. Morbi blandit libero ac massa laoreet auctor. Aliquam in massa eu nulla varius dictum non ut purus.  
  </p>  
</div>

and in our JavaScript code, we write the following code to set designMode to 'on' :

document.designMode = 'on';

Then we can edit the text that are displayed on the screen in the browser. This flag is very handy for fiddling with the content of the page. Once we refresh the page, we get back to the output that we have rendered from our saved code, so we don’t have to worry about it doing anything undesirable that’s permanent.

window.document.dir

The dir property of the document object is a read only property that returns a string that represents the direction of the text of the document, whether it’s left to right which is the default, or right to left. The possible values are 'rtl' for right to left and 'ltr' for left to right. For example, we can log the dir property with the following code:

console.log(document.dir);

Then we should get 'ltr' for most English pages in most browsers.

window.document.domain

The domain property let us get and set the domain part of the origin of the current document. If the document is inside a sandboxed iframe , the document has no browsing context, the effective domain is null , the given value isn’t equal to the document’s effective domain (which is the origin’s host or domain), or document-domain Feature-Policy is enabled, then a SecurityError will be thrown when document.domain is attempted to be set. The assignment is stopped in the cases above to prevent violation of the same origin policy and to prevent third party code from running in unauthorized locations. For example, if we run:

document.domain = 'mozilla.org';

in the developer’s console on a website that doesn’t have mozilla.org as the domain, then we will get the SecurityError . If we run it on mozilla.org , then the assignment will succeed. We can also use document.domain as a getter. If we run document.domain on https://developer.mozilla.org/en-US/docs/Web/API/Document then we get “developer.mozilla.org” .

window.document.lastModified

To get the date and time on which the current document was last modified, we can use the document object’s lastModified property. It’s a read only property that returns a string of when the document was last modified. For example, we can log it as is and get the date string of the object like we do in the code below:

console.log(document.lastModified);

We should get something like:

11/10/2019 13:22:54

as the output of the console.log . We can also convert it into a Date object by passing it straight into the Date object like in the following code:

console.log(new Date(document.lastModified));

Then we get something like:

Sun Nov 10 2019 13:24:06 GMT-0800 (Pacific Standard Time)

from the console.log output. We can also convert it to milliseconds since January 1, 1970 by using the Number function, the Date.parse method or the unary + operator in front of the date object like in the following code:

console.log(+new Date(document.lastModified));  
console.log(Number(new Date(document.lastModified)));  
console.log(Date.parse(document.lastModified));

All 3 lines of code above should get us the same milliseconds value, something like 1573421113000 .

In this article, we looked at the defaultView , designMode , dir, domain, and lastModified properties. The defaultView property is a read only property that returns the window object associated with the current document. The domain property let us get and set the domain part of the origin of the current document. The designMode property controls whether is the entire document is editable. This property is handy since we can set it to 'on' when we want to fiddle with the page without saving anything. The dir property of the document object is a read only property that returns a string that represents the direction of the text of the document. To get the date and time on which the current document was last modified, we can use the document object’s lastModified property and convert it to a Date object or change it to milliseconds since January 1, 1970.

Categories
Vuetify

Vuetify — Radio Buttons and Switches

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Radio Buttons

We can add radio buttons with the v-radio component.

For example, we can write:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <p>{{ radios }}</p>
        <v-radio-group v-model="radios" :mandatory="false">
          <v-radio label="Radio 1" value="radio-1"></v-radio>
          <v-radio label="Radio 2" value="radio-2"></v-radio>
        </v-radio-group>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    radios: '',
  }),
};
</script>

Setting the mandatory prop to false makes it optional.

Radios Buttons Direction

Radio buttons can be in a row or in a column.

For instance, we can write:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <p>{{ radios }}</p>
        <v-radio-group v-model="radios" column>
          <v-radio label="Radio 1" value="radio-1"></v-radio>
          <v-radio label="Radio 2" value="radio-2"></v-radio>
        </v-radio-group>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    radios: "",
  }),
};
</script>

to display the radio buttons in a column.

We can make them display in a row with a row prop:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <p>{{ radios }}</p>
        <v-radio-group v-model="radios" row>
          <v-radio label="Radio 1" value="radio-1"></v-radio>
          <v-radio label="Radio 2" value="radio-2"></v-radio>
        </v-radio-group>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    radios: "",
  }),
};
</script>

Radios Button Colors

The colors of radio buttons can be changed with the color prop:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <p>{{ radios }}</p>
        <v-radio-group v-model="radios">
          <v-radio label="Radio 1" value="radio-1" color="red"></v-radio>
          <v-radio label="Radio 2" value="radio-2" color="red"></v-radio>
        </v-radio-group>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    radios: "",
  }),
};
</script>

We change the radio button color with the color prop on each button.

Switches

We can add switches with the v-switch component.

For example, we can write:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <v-container fluid>
          <v-switch v-model="sw" :label="`Switch: ${sw.toString()}`"></v-switch>
        </v-container>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    sw: false,
  }),
};
</script>

We have the v-switch with v-model binding to a boolean state.

Switches Array

We can have multiple switches that bind to the same variable.

For example, we write:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <v-container fluid>
          <p>{{ people }}</p>
          <v-switch v-model="people" label="james" value="james"></v-switch>
          <v-switch v-model="people" label="mary" value="mary"></v-switch>
        </v-container>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    people: [],
  }),
};
</script>

We have the value prop which will be added to the people array if we check it.

Conclusion

Vuetify provides us with radio buttons and switches.

Categories
Vuetify

Vuetify — Checkboxes

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Checkboxes

We can add checkboxes with the v-checkbox component.

For instance, we can write:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <v-checkbox v-model="checked" :label="`Checkbox: ${checked.toString()}`"></v-checkbox>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    checked: false,
  }),
};
</script>

We add the v-model directive to bind it to a state value.

Then we displayed the checked value in the label .

Also, we can have multiple checkboxes that bind to the same value.

This way, the state would be an array:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <p>{{ selected }}</p>
        <v-checkbox v-model="selected" label="james" value="james"></v-checkbox>
        <v-checkbox v-model="selected" label="mary" value="mary"></v-checkbox>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    selected: [],
  }),
};
</script>

We added the value prop so that when the checkbox is checked, the value will be in the selected array.

Checkbox States

A check box can also be indeterminate.

We can add the indeterminate prop to make it indeterminate:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <v-checkbox value indeterminate></v-checkbox>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

They can also be disabled:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <v-checkbox input-value="true" value disabled></v-checkbox>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

Checkbox Colors

We can change the color of the checkbox with the color prop:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <v-checkbox v-model="checked" label="red" color="red" value="red" hide-details></v-checkbox>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    checked: false,
  }),
};
</script>

We have a red checkbox since we set color to red .

Checkboxes Inline with a Text Field

We can add checkboxes that are inline with a text field.

To do that, we write:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <v-row align="center">
          <v-checkbox v-model="checked" hide-details class="shrink mr-2 mt-0"></v-checkbox>
          <v-text-field label="Include files"></v-text-field>
        </v-row>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    checked: false,
  }),
};
</script>

We put the checkbox and text field in the same v-row to make them display side by side.

Conclusion

We can add checkboxes with various styles and behavior with Vuetify.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Skeleton and Slide Item

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.

Square Skeleton

We can make the skeleton corners square with the square 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-skeleton square></q-skeleton>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We can set the color of the skeleton by setting the class for the color:

<!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-skeleton class="bg-accent" type="circle"></q-skeleton>
          <br />
          <q-skeleton class="bg-teal"></q-skeleton>
          <br />
          <q-skeleton class="bg-orange" animation="pulse-y"></q-skeleton>
          <br />
          <q-skeleton class="bg-indigo"></q-skeleton>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We can set the skeleton border styles with our own class:

<!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>
      .custom-skeleton-border {
        border-radius: 10px 0 24px 4px;
        border: 1px solid #aaa;
      }
    </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-skeleton
            width="100px"
            height="50px"
            class="custom-skeleton-border"
          >
          </q-skeleton>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

Slide Item

We can add slide items with the q-slide-item component.

It’s a container that does something when we slide it left or right.

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-slide-item @left="onLeft" @right="onRight">
            <template v-slot:left>
              <q-icon name="done"></q-icon>
            </template>
            <template v-slot:right>
              <q-icon name="alarm"></q-icon>
            </template>

            <q-item>
              <q-item-section avatar>
                <q-avatar
                  color="primary"
                  text-color="white"
                  icon="bluetooth"
                ></q-avatar>
              </q-item-section>
              <q-item-section>Icons only</q-item-section>
            </q-item>
          </q-slide-item>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {},
        methods: {
          onLeft({ reset }) {
            this.$q.notify("Left action triggered. Resetting in 1 second.");
            this.finalize(reset);
          },

          onRight({ reset }) {
            this.$q.notify("Right action triggered. Resetting in 1 second.");
            this.finalize(reset);
          },

          finalize(reset) {
            this.timer = setTimeout(() => {
              reset();
            }, 1000);
          }
        }
      });
    </script>
  </body>
</html>

We add a slide item with the q-slide-item component.

And we populate the content we want to display when the left slide action is triggered with the left slot.

And we can do the same with the right slot to populate content when the right slide action is triggered.

We listen to the left and right events to listen for each action.

The parameter of the event handlers has the reset method to let us reset the slide item to the initial state.

Conclusion

We can add a placeholder with various styles and we can add slide items to add an item that lets us show something when we slide it.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Skeleton

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.

Skeleton

We can add placeholder items that we display when data is loading with the q-skeleton 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 row">
          <q-card style="max-width: 300px;">
            <q-item>
              <q-item-section avatar>
                <q-skeleton type="QAvatar"></q-skeleton>
              </q-item-section>

              <q-item-section>
                <q-item-label>
                  <q-skeleton type="text"></q-skeleton>
                </q-item-label>
                <q-item-label caption>
                  <q-skeleton type="text"></q-skeleton>
                </q-item-label>
              </q-item-section>
            </q-item>

            <q-skeleton height="200px" square></q-skeleton>

            <q-card-actions align="right" class="q-gutter-md">
              <q-skeleton type="QBtn"></q-skeleton>
              <q-skeleton type="QBtn"></q-skeleton>
            </q-card-actions>
          </q-card>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We set the type prop to set what kind of skeleton we want to show.

QAvatar shows an avatar placeholder.

QBtn shows a button placeholder.

text shows a text placeholder.

Other options for the type prop include:

  • QSlider
  • rect
  • circle
  • QBadge
  • QChip
  • QToolbar
  • QCheckbox
  • QRadio
  • QToggle
  • QRange
  • QInput

We can add animation effects for q-skeleton components.

We can set it by setting the animation 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 row">
          <q-card flat bordered style="width: 250px;">
            <q-card-section>
              <div class="text-caption">wave</div>
            </q-card-section>

            <q-separator></q-separator>

            <q-card-section>
              <q-skeleton animation="wave"></q-skeleton>
            </q-card-section>
          </q-card>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

Other options for the animation prop include:

  • pulse
  • pulse-x
  • pulse-y
  • fade
  • blink
  • none

We can set the size of the q-skeleton with the size , width and height 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"
      >
        <div class="q-pa-md">
          <q-skeleton type="circle" size="100px"></q-skeleton>
          <br />
          <q-skeleton width="150px"></q-skeleton>
          <br />
          <q-skeleton height="150px"></q-skeleton>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We can add a border to the skeletons with the bordered 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-skeleton bordered type="circle"></q-skeleton>
          <br />
          <q-skeleton bordered></q-skeleton>
          <br />
          <q-skeleton bordered square></q-skeleton>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

Conclusion

We can add placeholders to display when items are loading with the q-skeleton component.