Switching Between Grid View
and List View With Vue.js
Represent any array of data and switch between visualizations
Vue.js is a framework with high potential. It’s easy to learn, fast, and light in terms
of bytes. If you’re a beginner, you could start with these articles:
How To Build Your First Vue.js Application
Instant Search With Vue.js and Axios
Now I’m going to continue my journey through this framework with this piece
about how to make a Vue application that represents text data taken from an array
and switch its visualization from a list view to a grid view.
You’ll find the final result in my repository.
First Steps
First of all, let’s create three new files:
index.html
app.js
style.css
Add to index.html the reference to the style sheet, to our JavaScript file, and, of
course, to Vue.js:
<head>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<link href="style.css" rel="stylesheet" />
</head>
Then imagine our application layout:
Our application will have:
A button to switch between grid view and list view
A button to switch between different arrays of data, in order to show that the
application can render different collections
A standard grid view, composed of column name as first row and each element
as a row
A list view where each element is an item of the vertical collection, with an
image
Grid View Without Vue.js
Without Vue.js the grid view structure may look like this:
<div
id="app-
gridview">
<div>
<button class="button"><span>Switch to ListView</span></button>
<button class="button"><span>Switch to books data</span></button>
</div>
<div class="grid-wrapper">
<div class="grid-row">
<div class="grid-header">Column 1</div>
<div class="grid-header">Column 2</div>
<div class="grid-header">Column 3</div>
</div>
<!-- GridView structure -->
<div class="grid-row">
<div class="list-row-item">
<div>Column 1 Value a</div>
<div>Column 2 Value b</div>
<div>Column 3 Value c</div>
</div>
<div class="list-row-item">
<div>Column 1 Value d</div>
<div>Column 2 Value e</div>
<div>Column 3 Value f</div>
</div>
</div>
</div>
</div>
As you can see, I didn’t use the table tag, but just div. This is
helpful to better switch the representation just with css.
This is the style:
.grid-
wrapper
{
display: table;
border: 4px solid #336699;
border-radius: 6px;
transition: all ease 0.5s;
}
.grid-header {
font-weight: bold;
background: #336699;
color: white;
border-bottom: 4px solid #f6f6f6;
}
.grid-row {
display: table-row;
}
.grid-row > div {
display: table-cell;
padding: 10px 20px;
}
.grid-wrapper > div:nth-child(even) {
background: #f6f6f6;
transition: all ease 0.4s;
}
.grid-wrapper > div:nth-child(odd) {
background: #fafafa;
transition: all ease 0.4s;
}
.grid-wrapper > div:hover {
background: #a9d6ff;
transition: all ease 0.4s;
}
The most important things to notice are:
grid-wrapper, display: table
grid-row, display: table-row
It looks like this:
List View Without Vue.js
Without Vue.js the list view structure may look like this:
<div
class="list-
wrapper">
<!-- ListView structure -->
<div class="list-row">
<img src="images/a.jpg" class="list-image" />
<div class="list-property">
<div class="list-row-item">
<div class="list-property-name">Column 1</div>
<div>Value a</div>
</div>
<div class="list-row-item">
<div class="list-property-name">Column 2</div>
<div>Value b</div>
</div>
<div class="list-row-item">
<div class="list-property-name">Column 3</div>
<div>Value c</div>
</div>
</div>
</div>
<!-- And many others... -->
</div>
The style is pretty easy, just a combined display:
grid with flexbox:
.list-
row {
padding: 10px;
margin: 10px;
background: white;
border-radius: 6px;
-webkit-box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.37);
-moz-box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.37);
box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.37);
display: grid;
grid-template-columns: auto 1fr;
width: 600px;
}
.list-row-item {
display: grid;
grid-template-columns: 150px 1fr;
padding: 4px;
transition: all 0.5s;
}
.list-property {
display: flex;
flex-direction: column;
justify-content: space-between;
}
.list-property-name {
font-weight: bold;
transition: all 0.5s;
}
.list-image {
width: 150px;
border-radius: 6px;
margin-right: 10px;
}
It looks like this:
Vue.js Integration
The object to be represented should be something like:
var
booksData
= {
columns: [
"Id",
"Name",
"Author",
"Theme",
"Rating"
],
data: [
{ Id: 1, Name: "The look of love", Author: "George Blue", Theme:
"Drama", Rating: "*****", ImagePath: "images/a.jpg" },
{ Id: 2, Name: "20 vegetarian dishes", Author: "Francesco Bonizzi",
Theme: "Cooking", Rating: "****", ImagePath: "images/b.jpg" },
{ Id: 3, Name: "How to be happy", Author: "Asdrubale Anselmi",
Theme: "Self help", Rating: "*", ImagePath: "images/c.jpg" },
{ Id: 4, Name: "The last bee", Author: "John Dorian", Theme:
"Nature", Rating: "****", ImagePath: "images/d.jpg" }
]
};
Notice that it has two arrays:
: with just the names of each property to be
columns
rendered
: an array of objects with the same properties as
data
mentioned in columns
It’s time to implement our Vue application:
var
gridviewApp
= new Vue({
el: '#app-gridview',
data: {
gridData: cartData,
buttonSwitchViewText: "Switch to ListView",
buttonSwitchDataText: "Switch to books data",
isGridView: true,
isBookData: false
},
methods: {
switchView: function() {
if (this.isGridView) {
this.buttonSwitchViewText = "Switch to GridView";
}
else {
this.buttonSwitchViewText = "Switch to ListView";
}
this.isGridView = !this.isGridView;
},
switchData: function () {
if (this.isBookData) {
this.buttonSwitchDataText = "Switch to books data";
this.gridData = cartData;
}
else {
this.buttonSwitchDataText = "Switch to shop data";
this.gridData = booksData;
}
this.isBookData = !this.isBookData;
}
});
The Vue application is pretty easy:
property is used to hide/show the grid
isGridView
layout or the list layout.
property is used to change the
isBookData
represented data. (You won’t need this in
production; it’s just for purposes of this piece.)
You will see all the test data in the full code in the
repository.
The interesting part is the HTML structure, which is a
combination of:
used to toggle list/grid CSS classes
v-bind:class
based on the isGridViewCondition
used to render the array values and column
v-for
names
v-ifto hide/show some layouts based on the
selected representation
And here’s the final result:
You can find the whole code here.