During the first part of Working with Vuetify, I described how the framework Vuetify is, and how you can work with a predefined template.
It is time to set up everything for creating the menuapp component, so, let’s copy the whole template code in the template property of the compoment because we are not working with .vue files, but with Javascript.
As a matetr of fact, we need to make some changes to the original code of <template></template> of google-youtube.vue, because in other case, you will get some errores. The changes are:
- You must include some new properties on the data, such as source, a property that it is recived by the template’s component, and the list of items to show.
- You need a method for getting the user’s image (because you will get an error due to `)
With these two changes, you have “cloned” the YouTube template from Vuetify website, exactly as the original, but adapted to our way of programming.
The full code is like this::
const menuapp = Vue.component('menu-app', {
data() {
return {
drawer: null,
items: [
{ icon: 'trending_up', text: 'Most Popular' },
{ icon: 'subscriptions', text: 'Subscriptions' },
{ icon: 'history', text: 'History' },
{ icon: 'featured_play_list', text: 'Playlists' },
{ icon: 'watch_later', text: 'Watch Later' },
],
items2: [
{ picture: 28, text: 'Joseph' },
{ picture: 38, text: 'Apple' },
{ picture: 48, text: 'Xbox Ahoy' },
{ picture: 58, text: 'Nokia' },
{ picture: 78, text: 'MKBHD' },
],
source: ''
}
},
methods: {
getuser(info) {
return https://randomuser.me/api/portraits/men/${info.picture}.jpg
;
},
},
template:
`
<v-app id="inspire">
<v-navigation-drawer
v-model="drawer"
app
clipped
>
<v-list dense>
<v-list-item
v-for="item in items"
:key="item.text"
@click=""
>
<v-list-item-action>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>
{{ item.text }}
</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-subheader class="mt-4 grey--text text--darken-1">SUBSCRIPTIONS</v-subheader>
<v-list>
<v-list-item
v-for="item in items2"
:key="item.text"
@click=""
>
<v-list-item-avatar>
<img
:src="getuser(item.picture)"
alt=""
>
</v-list-item-avatar>
<v-list-item-title v-text="item.text"></v-list-item-title>
</v-list-item>
</v-list>
<v-list-item
class="mt-4"
@click=""
>
<v-list-item-action>
<v-icon color="grey darken-1">mdi-plus-circle-outline</v-icon>
</v-list-item-action>
<v-list-item-title class="grey--text text--darken-1">Browse Channels</v-list-item-title>
</v-list-item>
<v-list-item @click="">
<v-list-item-action>
<v-icon color="grey darken-1">mdi-settings</v-icon>
</v-list-item-action>
<v-list-item-title class="grey--text text--darken-1">Manage Subscriptions</v-list-item-title>
</v-list-item>
</v-list>
</v-navigation-drawer>
<v-app-bar
app
clipped-left
color="red"
dense
>
<v-app-bar-nav-icon @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
<v-icon class="mx-4">fab fa-youtube</v-icon>
<v-toolbar-title class="mr-12 align-center">
<span class="title">Manejando Datos Template {{ version }}</span>
</v-toolbar-title>
<div class="flex-grow-1"></div>
<v-row
align="center"
style="max-width: 650px"
>
<v-text-field
:append-icon-cb="() => {}"
placeholder="Search..."
single-line
append-icon="search"
color="white"
hide-details
></v-text-field>
</v-row>
</v-app-bar>
<v-content>
<v-container class="fill-height">
<v-row
justify="center"
align="center"
>
<v-col class="shrink">
<v-tooltip right>
<template v-slot:activator="{ on }">
<v-btn
:href="source"
icon
large
target="_blank"
v-on="on"
>
<v-icon large>mdi-code-tags</v-icon>
</v-btn>
</template>
<span>Source</span>
</v-tooltip>
<v-tooltip right>
<template v-slot:activator="{ on }">
<v-btn
icon
large
href="https://codepen.io/johnjleider/pen/aezMOO"
target="_blank"
v-on="on"
>
<v-icon large>mdi-codepen</v-icon>
</v-btn>
</template>
<span>Codepen</span>
</v-tooltip>
</v-col>
</v-row>
</v-container>
</v-content>
</v-app>
`
})
The result of our work is like this, and we almost have it finished:

As you can imagine, the result will be exactly identical as the original template, but still you need a very important detail to fix: inicialize everything. To do that, let’s go to the file where the vue instance is created:
scripts/index.js
This is the file that set up Vuetify (you also need to work here when including the store or when you need to use vue-router!).
The code is simple:
const bus = new Vue();
const vuetifyOptions = { };
Vue.use(Vuetify);
const app = new Vue({
el: '#app',
vuetify: new Vuetify(vuetifyOptions),
template:
`
<v-app v-cloak>
<transition mode="out-in" name="fade">
<menu-app></menu-app>
</transition>
</v-app>`
});
I have included a bus variable as a vue object because this is an option to emit events and change information between components. Although I am not using it in this series, it is interesting to have available this option.
On the other hand, I need to configure vue for working with vuetify, but also, this is the place where you can modify the vuetify’s configuration (I don’t change anything, but you can do it, because there is several options available with vuetify).
To end with, the component include a small HTML code in the template for starting the menu. Also, it is important that you must not name the component with predefined HTML tags, such as menu, and that’s why I call it menu-app.
Now, at the end of part 2, everything is working as expected with the template, that you have available at GitHub. Next parts 3 and 4 will be dedicated to VueX and to modules at VueX, while parts 5 will be dedicated to changed in order to get more functionality!
Happy coding!