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.
Horizontal Virtual Scrolling
We can add the virtual-scroll-horizontal
prop to make the virtual scrolling container horizontal:
<!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-virtual-scroll
style="max-height: 300px;"
:items="heavyList"
separator
virtual-scroll-horizontal
>
<template v-slot="{ item, index }">
<q-item :key="index" dense>
<q-item-section>
<q-item-label>
#{{ index }} - {{ item.label }}
</q-item-label>
</q-item-section>
</q-item>
</template>
</q-virtual-scroll>
</div>
<script>
const maxSize = 10000;
const heavyList = [];
for (let i = 0; i < maxSize; i++) {
heavyList.push({
label: `option ${i}`
});
}
new Vue({
el: "#q-app",
data: {
heavyList
}
});
</script>
</body>
</html>
Customized Item Template
We can customize the item template to display items the way we want:
<!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-virtual-scroll style="max-height: 300px;" :items="heavyList" separator>
<template v-slot="{ item, index }">
<q-banner
v-if="item.banner === true"
class="bg-black text-white q-py-xl"
:key="index"
>
#{{ index }} - {{ item.label }}
</q-banner>
<q-item v-else :key="index" dense clickable>
<q-item-section>
<q-item-label>
#{{ index }} - {{ item.label }}
</q-item-label>
</q-item-section>
</q-item>
</template>
</q-virtual-scroll>
</div>
<script>
const maxSize = 10000;
const heavyList = [];
for (let i = 0; i < maxSize; i++) {
heavyList.push({
label: `option ${i}`,
banner: i === 0
});
}
new Vue({
el: "#q-app",
data: {
heavyList
}
});
</script>
</body>
</html>
We just put the item template in the default slot.
Table Style Virtual Scrolling Container
Also, we can display the items in a table style virtual scrolling container:
<!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-virtual-scroll
type="table"
style="max-height: 70vh;"
:virtual-scroll-item-size="48"
:virtual-scroll-sticky-size-start="48"
:virtual-scroll-sticky-size-end="32"
:items="heavyList"
>
<template v-slot="{ item: row, index }">
<tr :key="index">
<td>#{{ index }}</td>
<td v-for="col in columns" :key="index + '-' + col">
{{ row[col] }}
</td>
</tr>
</template>
</q-virtual-scroll>
</div>
<script>
const data = [
{
name: "Frozen Yogurt",
calories: 159,
fat: 6.0,
carbs: 24
},
{
name: "Ice cream sandwich",
calories: 237,
fat: 9.0,
carbs: 37
},
{
name: "Eclair",
calories: 262,
fat: 16.0,
carbs: 23
},
{
name: "Cupcake",
calories: 305,
fat: 3.7,
carbs: 67
},
{
name: "Gingerbread",
calories: 356,
fat: 16.0,
carbs: 49
},
{
name: "Jelly bean",
calories: 375,
fat: 0.0,
carbs: 94
},
{
name: "Lollipop",
calories: 392,
fat: 0.2,
carbs: 98
},
{
name: "Honeycomb",
calories: 408,
fat: 3.2,
carbs: 87
},
{
name: "Donut",
calories: 452,
fat: 25.0,
carbs: 51
},
{
name: "KitKat",
calories: 518,
fat: 26.0,
carbs: 65
}
];
const columns = ["name", "calories", "fat", "carbs"];
const heavyList = [];
for (let i = 0; i <= 1000; i++) {
heavyList.push(...data);
}
Object.freeze(heavyList);
Object.freeze(columns);
new Vue({
el: "#q-app",
data: {
columns,
heavyList
}
});
</script>
</body>
</html>
We render the columns in the default slot.
And we set the virtual-scroll-item-size
prop to change height or width of the item in pixels, depending on if the list is vertical or horizontal respectively
The virtual-scroll-sticky-size-start
prop to change the height or width of the sticky part in pixels, depending on if the list is vertical or horizontal respectively.
And the virtual-scroll-sticky-size-end
prop to change the height or width of the bottom sticky part in pixels, depending on if the list is vertical or horizontal respectively.
Conclusion
We can add a virtual scrolling container with various styles with Quasar’s q-virtual-scroll
component.