Trabajando con Vuetify – Parte 2

Posted by in HTML5

En la primera parte de trabajando con Vuetify, se describió cómo es el framework Vuetify, y cómo íbamos a trabajar a partir de una plantilla predeterminada.

Para preparar el componente menuapp, copiamos todo el template en la correspondiente propiedad del componente (dado que no estamos trabajando con archivos .vue, sino con Javascript directamente).

Adicionalmente, hay que realizar varias modificaciones a partir del código original de <template></template> de google-youtube.vue, entre ellas:

  • Incluir diversas propiedades en el data, entre ellas source, que es una propiedad que recibe el componente de la plantilla, y la lista de items a mostrar.
  • Crear un método (methods) para recuperar la imagen de un usuario (porque nos da un error si copiamos tal cual debido al uso de comillas y `)

Con estas pequeñas modificaciones, ya tenemos «clonada» la plantilla de YouTube procedente de Vuetify, tal y cómo aparece en el original, pero adaptada a nuestra forma de trabajo.

El código completo de esta versión es:

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>

`

})

El resultado que queremos obtener es este, y casi lo tenemos:

Plantilla Manejando Datos para Vuetify 2

Cómo puede comprobarse, el resultado será exactamente el mismo que la plantilla original, pero aun nos falta un detalle importante: inicializar todo. Para ello, recurrimos al índice dónde se inicia vue.

scripts/index.js

Este archivo es el que inicializa Vuetify (también será necesario trabajar aquí para incluir el store o las rutas si utilizamos vue-router (entre otros!).

El código es 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>`
});

Se ha incluido una variable bus de vue para permitir enviar eventos entre componentes, y que aunque no la utilizaremos, pero siempre es interesante disponer de esta posibilidad.

Por otro lado, configuramos vue para que pueda trabajar con vuetify, además, será el sitio donde podremos configurar muchas cosas (yo siempre lo dejo tal y cómo veis y no me complico, pero hay múltiples opciones para configurar vuetify).

Y por último, el componente incluye una pequeña plantilla para inicializar el menú. Además, es importante no nombrar los componentes con nombres que ya estén definidos en HTML, cómo es el elemento menu, por eso, yo lo llamo menu-app.

Ya está todo operativo para que te funcione la plantilla. Y hasta aquí, la parte 2, que tienes disponible en GitHub. Las parte 3 y 4 la dedicaremos a VueX y a los módulos de VueX, mientras que más adelante re incluirán unas cuantas modificaciones y le daremos más funcionalidad.

Happy coding!