Trabajando con Vuetify: algunas mejoras – parte 5

Posted by in Javascript y TypeScript

Seguimos aprendiendo con la serie Trabajando con Vuetify, (parte 2) en donde hemos empezado trabajando con una de las plantillas predefinidas, y la hemos ido adaptando para trabajar sin necesidad de NodeJs ni Webpack ni compilación: todo y solo Javascript.

En las partes 3 y 4, hemos aprendido sobre VueX, y también los módulos, pero casi no hemos incluido ninguna funcionalidad. Ahora tocará trabajar con el menu, que casi no se tocó anteriormente, salvo para incluir el nombre y versión guardados en el store.

Si te ha gustado la serie, te encantará el final, y te animo a que contribuyas al mantenimiento del blog.

Preparando las opciones del menú de la izquierda

En el menú, en data, se incluyen dos listas: la primera corresponde con la parte de arriba, y la segunda con las suscripciones. Vamos a eliminar la segunda para centrarnos en la primera (es decir, eliminaremos item2 y también source y tampoco nos hará falta ya el método getuser).

A su vez, vamos a incluir nuevas propiedades: menu (para saber qué componente mostrar), y colores (para dar formato homogéneo a la aplicación, y dónde hemos seleccionado el orange). Además, para controlar el menú de la izquierda, pondremos draw a false (o true, si queremos que se inicie ya visible). Al final, esta parte del componente queda así:

data() {
		return {
			drawer: true,
            items: [
                { icon: 'trending_up', text: 'Most Popular', action: 'popular', color_item_text: 'red--text', icon_class: 'red--text' },
                { icon: 'subscriptions', text: 'Subscriptions', action: 'suscripciones' },
                { divider: true , class: 'blue' },
                { icon: 'history', text: 'History', action: 'historia' },
                { icon: 'featured_play_list', text: 'Playlists', action: 'playlist'},
                { icon: 'watch_later', text: 'Watch Later', action: 'later' },
            ],
			colores: {
				color: 'orange',
				color_list: 'blue lighten-4',
				color_item_text: 'red',
			},
			menu: '',
		}
	},

La carga dinámica del menú se produce por este código, asociado a la propiedad item:

<v-list-item
          v-for="item in items"
          :key="item.text"
          link
        >
          <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>

Sin embargo, yo he terminado creando un nuevo componente para mejorar el código anterior. Habrás notado que la variable item amplia las posibilidades, permitiéndole asignar un color determinado a cada opción, así como un color distinto al icono. Pero lo más interesante es incluir una propiedad action que es la que nos va a decir qué acción desarrollar:


const sublistado2 = Vue.component('sublistado2', {
	props: {
		menulist: { required: true, type: Array }, 
		colores: { 
			required: false,
			type: Object,
			default: function () { return {} }
		},
	},
	data() {
		return {
			color_list_def: 'grey lighten-4',
			color_item_text_def: 'black--text',
		}
	}, 
	computed: {
		color_list() { return this.colores.color_list || this.color_list_def },
		color_item_text() { return this.colores.color_item_text || this.color_item_text_def },
	},
	methods: {
		accion(item) {
			this.$emit('accion', item.action);
		},
	},
	template: `
	<v-list dense :class="color_list">
		<template v-for="(item, i) in menulist">
			  <v-layout v-if="item.heading" :key="i" align-center>
				<v-flex xs12>
				  <v-subheader v-if="item.heading" :class="item.class">
					{{ item.heading }}
				  </v-subheader>
				</v-flex>
			  </v-layout>
			  
			  <v-list-item v-else-if="item.text" :key="i" @click.stop="accion(item)">
				<v-list-item-action v-if="item.icon">
				  <v-icon :class="item.icon_class">{{ item.icon }}</v-icon>
				</v-list-item-action>
				<v-list-item-content>
				  <v-list-item-title :class="item.color_item_text">
					{{ item.text }}
				  </v-list-item-title>
				</v-list-item-content>
			  </v-list-item>
			  <v-divider v-if="item.divider" :key="i" class="my-1" :class="item.class"></v-divider>
		</template>
		<slot ></slot>
	</v-list>	
	`
});

Este nuevo componente tiene más posibilidades, y reduce también el código de menu, e incluso se puede configurar para incluir separadores:

<sublistado2
			:menulist="items"
			:colores="colores"
			@accion="accion"
		></sublistado2>

Cómo puedes comprobar, tenemos un evento llamado accion, que hay que controlar, con el método accion cuyo código es el siguiente:

accion(action) {
			this.menu = action;
        },

Y así es cómo sabemos qué quiere ver el usuario.

De esta forma, es viable ir ampliando la plantilla inicial hasta darle funcionalidad.

En la zona de plantilla, incorporamos que muestre lo que ha seleccionado el usuario:

<v-main>
      <v-container class="fill-height">
        <v-row
          justify="center"
          align="center"
        >
          
		  <v-flex xs12 v-if="menu">
					<div align="center">
					{{ menu }}
					</div>
				  </v-flex>
		  
        </v-row>
      </v-container>
    </v-main>

Y el resultado es, por ejemplo, al pulsar en Subscriptions:

Plantilla mejorada

Y hasta aquí todo lo que ha incluido la serie Trabajar con Vuetify, dónde ya el resto queda a tu disposición, pues ya sabes cómo utilizar una plantilla predefinida de vuetify. En todo caso, es posible que haya una nueva y última entrada para trabajar, por ejemplo, con un formulario de login!

La verdad es que me hubiera gustado que alguien me hubiera expuesto esto que yo he hecho antes!

Happy coding!