First and foremost this is not an official whiskey review list. My objective here was to quickly stand up a searchable list with links to reviews for different whiskey. I am a fan of whiskey myself and figured this would be a great way to briefly walk through how it was created.
This site is an experiment with JAM stack. I am using Gridsome and Vuetify for the purposes of this experience.
Taking a quick search on GitHub I grabbed a tsv file and converted it to YAML. The list includes whiskey names, regions, scores, and a few other nice to know items.
We need to create our template for listing out the items in our whiskey YAML file. I am using four key value pairs - name, region, score, and link. This will be our Whiskies.vue component.
<template>
<v-container fluid>
<v-row>
<v-col cols="12">
<v-text-field
v-model="searchQuery"
label="Whisk(e)y Search"
outlined
></v-text-field>
</v-col>
<v-col cols="12" md="6" v-for="r of resultQuery" :key="r.nane">
<v-card
color="brown darken-3"
dark
class="elevation-5 py-3 px-3"
>
<div>
<v-card-title
class="headline"
v-text="r.name"
></v-card-title>
<v-card-subtitle>
<span class="font-weight-bold">Region:</span> {{r.region}}
</v-card-subtitle>
<v-card-text>
<v-banner
single-line
>
<div class="center">
<span style="margin-left:10px;">Rating:</span>
</div>
<template v-slot:actions>
<v-rating
empty-icon="star_outline"
full-icon="star"
half-icon="star_half_full"
length="5"
size="24"
:value="5"
readonly
color="white--text"
background-color="white"
></v-rating>
...
</template>
</v-banner>
</v-card-text>
<v-card-actions>
<v-btn
class="ml-2 mt-5 elevation-5"
outlined
rounded
small
:href="r.link"
target="_blank"
>
READ THE REVIEW
</v-btn>
</v-card-actions>
</div>
</v-card>
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
data() {
return {
searchQuery: ''
}
},
props: {
whisky: Array
},
computed: {
resultQuery() {
if (this.searchQuery.length > 2) {
return this.whisky.filter(item => {
return this.searchQuery
.toLowerCase()
.split(" ")
.every(v => item.name.toLowerCase().includes(v));
});
} else {
return this.whiskyLimited
}
},
whiskyLimited() {
return this.whisky.slice(0, 10)
}
}
}
</script>
This page is simple and will be used to display our Whiskies.vue component. We simply call this Whiskey.vue.
<template>
<Layout>
<v-container class="pt-5">
<v-row>
<v-col cols="12">
<div class="display-2 text-center my-5">Whiskey Ratings and Reviews</div>
<Whisky :whisky="whiskyData.whisky" />
</v-col>
</v-row>
</v-container>
</Layout>
</template>
<script>
import Whisky from "~/components/Whiskies";
import whiskyData from "~/data/whiskies.yml";
export default {
components: {
Whisky
},
data() {
return {
whiskyData
};
},
metaInfo: {
title: 'Whisk(e)y',
meta: [
{ key: 'description', name: 'description', content: 'Whisky reviews listed out for you!' }
],
link: [
{rel: 'canonical', href: process.env.GRIDSOME_BASE_URL + '/whiskey'}
]
}
};
</script>
As you can see this is really quick and simple. We could definitely spend some time cleaning up, and the above code snippets do not contain the rest of the dependencies. This should provide a good idea of how to build out a quick vue of otherwise boring data.
Gridsome, Vue.js, Vuetify offer such an efficient delivery model. This example is using a small data set, a little over 2000 records. You can see the performance advantages here even with the light amount of data.
Keep an eye out for other quick little bits. Cheers!