Categories
Quasar

Developing Vue Apps with the Quasar Library — Separator

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.

Separator

We can add a separator to separate various containers with the q-separator 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: 250px;">
            <q-card-section>
              <div class="text-h6">Title</div>
              <div class="text-subtitle2">by John Doe</div>
            </q-card-section>

            <q-separator></q-separator>

            <q-card-actions>
              <q-btn label="Share" color="primary" flat></q-btn>
              <q-btn label="Comment" color="secondary" flat></q-btn>
            </q-card-actions>
          </q-card>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We used q-separator to separate the q-card-section and q-card-actions with a line.

We can also use it to separate q-item s:

<!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-list
            class="bg-grey-10 text-white shadow-2 rounded-borders"
            style="max-width: 250px; width: 100%;"
          >
            <q-item>
              <q-item-section avatar>
                <q-avatar>
                  <img src="https://cdn.quasar.dev/img/avatar6.jpg" />
                </q-avatar>
              </q-item-section>
              <q-item-section>Alex</q-item-section>
            </q-item>

            <q-separator dark></q-separator>

            <q-item>
              <q-item-section avatar>
                <q-avatar>
                  <img src="https://cdn.quasar.dev/img/avatar3.jpg" />
                </q-avatar>
              </q-item-section>
              <q-item-section>Lily</q-item-section>
            </q-item>

            <q-item>
              <q-item-section avatar>
                <q-avatar>
                  <img src="https://cdn.quasar.dev/img/avatar5.jpg" />
                </q-avatar>
              </q-item-section>
              <q-item-section>Mary</q-item-section>
            </q-item>
          </q-list>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We can add the inset prop to add some margins to the separator:

<!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-list
            class="bg-grey-10 text-white shadow-2 rounded-borders"
            style="max-width: 250px; width: 100%;"
          >
            <q-item>
              <q-item-section avatar>
                <q-avatar>
                  <img src="https://cdn.quasar.dev/img/avatar6.jpg" />
                </q-avatar>
              </q-item-section>
              <q-item-section>Alex</q-item-section>
            </q-item>

            <q-separator dark inset></q-separator>

            <q-item>
              <q-item-section avatar>
                <q-avatar>
                  <img src="https://cdn.quasar.dev/img/avatar3.jpg" />
                </q-avatar>
              </q-item-section>
              <q-item-section>Lily</q-item-section>
            </q-item>

            <q-item>
              <q-item-section avatar>
                <q-avatar>
                  <img src="https://cdn.quasar.dev/img/avatar5.jpg" />
                </q-avatar>
              </q-item-section>
              <q-item-section>Mary</q-item-section>
            </q-item>
          </q-list>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We can add a margin to the card separator with the same 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 style="max-width: 250px;">
            <q-card-section>
              <div class="text-h6">Title</div>
              <div class="text-subtitle2">by John Doe</div>
            </q-card-section>

            <q-separator inset></q-separator>

            <q-card-section>
              Lorem ipsum dolor sit amet
            </q-card-section>
          </q-card>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

Conclusion

We can add a separator between list items and card sections with Quasar’s q-separator component.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Scroll Container Position and Scroll Event

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.

Change Scroll Container Position

We can change the scroll container position programmatically with the setScrollPosition method:

<!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 q-gutter-md q-mb-md">
            <q-btn
              :label="`Scroll to ${position}px`"
              color="primary"
              @click="scroll"
            ></q-btn>
            <q-btn
              :label="`Animate to ${position}px`"
              color="primary"
              @click="animateScroll"
            ></q-btn>
          </div>

          <q-scroll-area
            ref="scrollArea"
            style="height: 200px; max-width: 300px;"
            :delay="1200"
          >
            <div v-for="n in 100" :key="n" class="q-py-xs">
              Lorem ipsum dolor sit amet
            </div>
          </q-scroll-area>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          position: 300
        },
        methods: {
          scroll() {
            this.$refs.scrollArea.setScrollPosition(this.position);
            this.position = Math.floor(Math.random() * 100) * 20;
          },

          animateScroll() {
            this.$refs.scrollArea.setScrollPosition(this.position, 300);
            this.position = Math.floor(Math.random() * 100) * 20;
          }
        }
      });
    </script>
  </body>
</html>

The first argument of setScrollPosition is the scroll position to set and the 2nd argument is the delay.

Horizontal Scroll Container

We can add a horizontal scroll container with the horizontal 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-scroll-area
            horizontal
            style="height: 210px; width: 230px;"
            class="bg-grey-1 rounded-borders"
          >
            <div class="row no-wrap">
              <div
                v-for="n in 10"
                :key="n"
                style="width: 150px;"
                class="q-pa-sm"
              >
                Lorem ipsum dolor sit amet
              </div>
            </div>
          </q-scroll-area>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We can watch the scroll position of a scroll container by listening to the scroll event:

<!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-scroll-area
            style="height: 200px;"
            class="col"
            ref="first"
            @scroll="onScrollFirst"
          >
            <div v-for="n in 100" :key="n" class="q-pa-xs">
              Lorem ipsum dolor sit amet
            </div>
          </q-scroll-area>

          <q-scroll-area
            style="height: 200px;"
            class="col"
            ref="second"
            @scroll="onScrollSecond"
          >
            <div v-for="n in 100" :key="n" class="q-pa-xs">
              Lorem ipsum dolor sit amet
            </div>
          </q-scroll-area>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {},
        methods: {
          scroll(source, position) {
            if (this.ignoreSource === source) {
              this.ignoreSource = null;
              return;
            }

            const target = source === "first" ? "second" : "first";
            this.ignoreSource = target;
            this.$refs[target].setScrollPosition(position);
          },

          onScrollFirst({ verticalPosition }) {
            this.scroll("first", verticalPosition);
          },

          onScrollSecond({ verticalPosition }) {
            this.scroll("second", verticalPosition);
          }
        }
      });
    </script>
  </body>
</html>

The onScrollFirst and onScrollSecond methods are the scroll containers.

In each method, we call the scroll method to scroll the other scroll container by calling the setScrollPosition method of it.

The scroll position is set to the verticalPosition value.

Conclusion

We can set the scroll container position and watch scroll events with Quasar’s scroll container.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Scroll Container Style

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.

Scroll Container Content Style

We can set the scroll container’s content style with the content-style and content-active-style 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-scroll-area  
            style="height: 200px; max-width: 300px;"  
            :thumb-style="thumbStyle"  
            :content-style="contentStyle"  
            :content-active-style="contentActiveStyle"  
          >  
            <div v-for="n in 100" :key="n" class="q-py-xs">  
              Lorem ipsum dolor sit amet  
            </div>  
          </q-scroll-area>  
        </div>  
      </q-layout>  
    </div>  
    <script>  
      new Vue({  
        el: "#q-app",  
        data: {  
          thumbStyle: {  
            right: "4px",  
            borderRadius: "5px",  
            backgroundColor: "#027be3",  
            width: "5px",  
            opacity: 0.75  
          },  
          contentStyle: {  
            backgroundColor: "rgba(0,0,0,0.02)",  
            color: "#555"  
          },  
          contentActiveStyle: {  
            backgroundColor: "yellow",  
            color: "black"  
          }  
        }  
      });  
    </script>  
  </body>  
</html>

When we hover our mouse over the content, then the content-active-style styles are applied.

Otherwise, the content-style styles are applied.

We can set the background to a dark background with 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"  
    />  
  </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-scroll-area  
            style="height: 200px; max-width: 300px;"  
            dark  
            class="bg-dark text-white rounded-borders"  
          >  
            <div v-for="n in 100" :key="n" class="q-py-xs">  
              Lorem ipsum dolor sit amet  
            </div>  
          </q-scroll-area>  
        </div>  
      </q-layout>  
    </div>  
    <script>  
      new Vue({  
        el: "#q-app",  
        data: {}  
      });  
    </script>  
  </body>  
</html>

And we set the text to text-white to set the text to white.

We can control the scrollbar visibility with the visible 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-scroll-area style="height: 200px; max-width: 300px;" visible>  
            <div v-for="n in 100" :key="n" class="q-py-xs">  
              Lorem ipsum dolor sit amet  
            </div>  
          </q-scroll-area>  
        </div>  
      </q-layout>  
    </div>  
    <script>  
      new Vue({  
        el: "#q-app",  
        data: {}  
      });  
    </script>  
  </body>  
</html>

Scroll Bar Display Delay

We can change the delay when the scrollbar appears and disappears with the delay 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-scroll-area style="height: 200px; max-width: 300px;" :delay="1200">  
            <div v-for="n in 100" :key="n" class="q-py-xs">  
              Lorem ipsum dolor sit amet  
            </div>  
          </q-scroll-area>  
        </div>  
      </q-layout>  
    </div>  
    <script>  
      new Vue({  
        el: "#q-app",  
        data: {}  
      });  
    </script>  
  </body>  
</html>

Conclusion

We can set the scroll bar and content style of the scroll container with Quasar.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Responsive Carousel and Scroll 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 Carousel

We can wrap the q-responsive component around the q-carousel component to create a responsive carousel:

<!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" style="width: 500px; max-width: 100%;">
          <q-carousel swipeable animated arrows v-model="slide" infinite>
            <q-carousel-slide
              :name="1"
              img-src="https://cdn.quasar.dev/img/mountains.jpg"
            ></q-carousel-slide>
            <q-carousel-slide
              :name="2"
              img-src="https://cdn.quasar.dev/img/parallax1.jpg"
            ></q-carousel-slide>
            <q-carousel-slide
              :name="3"
              img-src="https://cdn.quasar.dev/img/parallax2.jpg"
            ></q-carousel-slide>

            <template v-slot:control>
              <q-carousel-control
                position="bottom"
                :offset="[16, 8]"
                class="text-white text-center rounded-borders"
                style="background: rgba(255, 255, 255, 0.2); padding: 4px 8px;"
              >
                Ratio 16:9
              </q-carousel-control>
            </template>
          </q-carousel>
        </q-responsive>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          slide: 1
        }
      });
    </script>
  </body>
</html>

We add the control slot to populate some content of the carousel.

We set the offset to push the content to the bottom.

We set the ratio prop to set the aspect ratio of the container.

The v-model directive is bound to the slide reactive property to set the index of the slide we navigate to.

Scroll Area

We can add a scroll container with the q-scroll-area 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"
      >
        <div class="q-pa-md">
          <q-scroll-area style="height: 200px; max-width: 300px;">
            <div v-for="n in 100" :key="n" class="q-py-xs">
              Lorem ipsum dolor sit amet
            </div>
          </q-scroll-area>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We set the height and max-width to make it scrollable when the content overflows the dimensions.

We can set the scrollbar style with the thumb-style and bar-style 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-scroll-area
            style="height: 200px; max-width: 300px;"
            :thumb-style="thumbStyle"
            :bar-style="barStyle"
          >
            <div v-for="n in 100" :key="n" class="q-py-xs">
              Lorem ipsum dolor sit amet
            </div>
          </q-scroll-area>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          thumbStyle: {
            right: "4px",
            borderRadius: "5px",
            backgroundColor: "#027be3",
            width: "5px",
            opacity: 0.75
          },

          barStyle: {
            right: "2px",
            borderRadius: "9px",
            backgroundColor: "#027be3",
            width: "9px",
            opacity: 0.2
          }
        }
      });
    </script>
  </body>
</html>

thumb-style sets the styles for the scroll bar button.

And bar-style sets the styles for the scroll bar.

Conclusion

We can add a responsive carousel and scroll container into our Vue app with Quasar.

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.