Aprendiendo VueJS sin hacer un TODO-List

El frontend cambia muchísimo, cada día salen frameworks nuevos, herramientas,… y por ello estar al día de todo es imposible. Pero eso no deja de lado que me apetezca mejorar mis habilidades de frontend y aprender un un poco como se trabaja con javascript más hallá de JQuery y de hacer Stackoverflow Driven Development.

37036473724_28163a121c_z
Matías Garrido – Flickr

Así que me he propuesto ir aprendiendo VueJS, porque creo que tiene una curva de aprendizaje bastante asequible y voy a ver resultados pronto sin demasiada frustración. Además hace tiempo que me encontré con este magnifico libro “Desarrolla aplicaciones con VueJS“, con el curso de CodelyTV sobre hacer TDD con VueJS y Jest y tuve la suerte de cruzarme con Dani Latorre de coding stones en la conferencia “Madrid Software Crafters” y charlar sobre VueJS, frontend actual y las charla que dieron en Codemotion.

Bueno pues es hora de empezar a darle caña a VueJS, la idea del post de hoy es montar un pequeño escaparate de productos, algo así como una tienda online pero sin botón de comprar y sin llamadas a ninguna API. El objetivo es crear una aplicación en VueJS, con una jerarquía de componentes (un componente padre y al menos un hijo) y familiarizarnos con la manera de crear compoentes y la estructura de un proyecto en VueJS.

Para desarrollar vamos a utilizar WebStorm, pero podría hacerse con Siblime o similar porque el objetivo es familiarizarnos con todo esto del frontend.

Lo primero es crear la estructura de carpetas del proyecto, para ello lo mejor es
utilizar vue-cli, para ello instalamos la herramienta desde un terminal y con la opción -g hacemos que sea global (que se pueda ejecutar en cualquier carpeta.

npm install -g vue-cli

Creamos una carpeta, que será donde tengamos el proyecto y ejecutamos vue-cli

mkdir aprendiendoVUEJS
cd aprendiendoVUEJS
vue init webpack-simple .

y seguimos las instrucciones de poner el nombre del proyecto y todo lo demás.
Al terminar tendremos una serie de ficheros, los más importantes son:

  • package.json es como composer.json de PHP, es donde están todas las dependencias del proyecto. También es donde podemos crear scripts para automatizar procesos, ahora tenemos 2 scripts dev y build
  • webpack.config.js es la configuración de webpack, el encargado de tratar con el JS, unirlos, mininimificarlo,…
  • La carpeta src que es donde estará el código de nuestra aplicación, ahora tenemos un pequeño ejemplo.
  • index.html que es el punto de entrada de la aplicación.

Lo primero que tenemos que hacer es instalar todas las dependencias con npm

npm install

Una vez que ha terminado, se habrá creado un fichero package-lock.json que es parecido a composer.lock y además tendremos una carpeta node_modules con todas las dependencias. Ahora ejecutando npm run dev se abrirá el navegador en http://localhost:8080 y aparecerá la página de VueJS de ejemplo funcionando.

Screen Shot 2018-03-17 at 09.30.52.png

¡Ya tenemos un ejemplo hecho en VueJs! Ahora vamos a seguir ampliándolo un poco.

Vamos a sacarle un poco más de partido a Vue añadiendo unos módulos muy útiles: vue-router y vuex.

  • vue-router: nos permite definir rutas para manejar dinámicamente los componentes de nuestra aplicación.
  • vuex: es un adminitrador de estados. Está inspirado en redux y lo que nos permite es que los componentes vayan cambiando de estado.
  • vuex-router-sync: sirve para inyectar información parte de la información de nuestro enrutador directamente en nuestro estado vuex, tranquilos, de momento lo instalamos que usandolo se e más fácil.
  • copy-webpack-plugin: para copiar los assets de un sitio a otro fácilmente

Suena complicado, pero no os preocupéis, poco a poco vamos a ir viendo como utilizarlos e integrándolos en nuestros componentes. Para instalarlos:

npm install --save vue-router
npm install --save vuex
npm install --save vuex-router-sync
npm install --save copy-webpack-plugin

La opción --save es para que npm descargue la ultima versión estable.

Empezando a escribir código

Ya tenemos todo instalado, ahora es hora de empezar a escribir código. La idea es hacer un pequeño catalogo online para así aprender un poco de Vue, routing y Vuex.
Como es una aplicación de ejemplo no vamos a liarnos usando una api externa, así que vamos a tener datos estáticos en un fichero. Para ello vamos a crear en src una carpeta llamada store y dentro un fichero llamado state.js que contendrá un array con los datos que mostraremos en el catálogo

export const state = {
 products: [
   {
     id: 1,
     name: 'Tortas Inés Rosales',
     price: 80.00,
     description: 'Tortas de Aceite Inés rosales',
     image: '/dist/images/products/tortas.jpg'
   },
   {
     id: 2,
     name: 'Mojama',
     price: 120.00,
     description: 'Mojama de Atún',
     image: '/dist/images/products/mojama.jpg'
   },
   {
     id: 3,
     name: 'Vino',
     price: 100,
     description: 'Vino de naranja',
     image: '/dist/images/products/vino_naranja.jpg'
   }
 ]
}

Este fichero será como nuestra “base de datos”, en una aplicación real aquí podríamos montar las llamadas a una API.

Las fotos de nuestros productos las pondremos en una carpeta llamada /dist/images/products/, si preferimos podemos utilizar url’s de imágenes o algún servicio de imágenes ramdom como https://picsum.photos/200/300/?random
Ahora dentro de store creamos un fichero llamada getters.js que es donde vamos a definir nuestras funciones de búsqueda

export const getters = {
   getProductById: (state, getters) => (id) => {
       return state.products.find(product => product.id == id)
   }
}

En un primer momento solo vamos a tener una búsqueda por id, así que lo que definimos es la función getProductById
Esta función busca dentro del array de products el product que coincida con el id

Por último creamos index.js dentro de store que es donde unimos el fichero state.js y getters.js

import Vue from 'vue'
import Vuex from 'vuex'
import { state } from './state.js'
import { getters } from './getters.js'

Vue.use(Vuex)

export default new Vuex.Store({
 state,
 getters
})

Para ampliar más información: https://medium.com/js-dojo/vuex-for-the-clueless-the-missing-primer-on-vues-application-data-store-33fa51ffc3af

Ya tenemos a Vuex funcionando, ahora vamos a por las rutas.

Construyendo las rutas

Básicamente vamos a tener una homepage con el listado de productos y tendremos también otra página para cada producto en detalle.
Así que registraremos 2 rutas.

Para ello creamos un directorio llamado router y dentro un fichero index.js

import VueRouter from 'vue-router'
import Vue from 'vue'
import ProductDetails from './../components/ProductDetails.vue'
import Home from './../components/Home.vue'

Vue.use(VueRouter)

export default new VueRouter({
 routes: [
   { path: '/products/:id', component: ProductDetails },
   { path: '/', component: Home },
 ]
})

Instanciamos un nuevo VueRouter y añadimos las 2 rutas y que componente se instancia en cada ruta.
Todavía no hemos creado ni un componente, pero no tenemos que preocuparnos.

Uniéndolo todo

Ya tenemos store y router así que ahora tenemos que unirlo todo. Para ello editamos el fichero main.js que viene incluido en el ejemplo.

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import { sync } from 'vuex-router-sync'
import store from './store'

sync(store, router)

new Vue({
 store,
 router,
 render: h => h(App)
}).$mount('#app')

Lo que estamos haciendo es crear una nueva app de Vue que colgará de un div que tanga un id #app

Creando los componentes

Así que ahora viene lo divertido y es crear los componentes. Tenemos los datos de los productos en state y tenemos 2 rutas una principal y otra de detalle creadas en route , así que vamos a crear 3 componentes:

  • Home: que será el componente principal
  • Product: que será un componente hijo de Home para ver los productos en la pagina principal.
  • ProductDetail: que será el componente donde mostremos toda la información en detalle.
  • TopContext: será el componente de arriba

Un pequeño esquema de como quedará todo sería más o menos así:

Dibujo sin título

Dentro de la carpeta components vamos a crear los 4 componentes:

Top Context

Nuestro primer componente será solo un link a la página principal

<template>
  
Vue.js Demo Store
</div> </template> export default { name: 'TopContext', }

 

Como vemos todos los componentes siempre tienen una parte template que es donde se escribe el HTML y/o codigo VueJS de templates (v-if, v-for, router….) y otra parte script que es donde escribimos el código javascript de ese componente.

En este caso en la parte de script solo declaramos un nombre. en la parte de template lo único que estamos haciendo es llamar a router y decirlo que queremos ir a la ruta / siempre.

ProductDetails

Ahora vamos con el componente de ProductDetails donde vamos a mostrar todos los datos que guardamos el el fichero state.js

<template>
  
{{ product.name }} {{product.description}} Su precio aproximado es de {{product.price}}$
</div> </template> export default { name: 'ProductDetails', computed: { id () { return this.$store.state.route.params.id }, product () { return this.$store.getters.getProductById(this.id) }, }, }

En la parte script lo que tenemos son 2 funciones, una llamada id que lo que devolver el id del producto que viene a través de la URL y otra llamada product que devuelve el elemento que tenemos guardado en el array.
Por otro lado tenemos el template que lo único que hace es ir mostrando los datos del producto en elementos html usando la sintaxis de VueJS.

HomePage

Este componente lo que hace es iterar por elarray de producot e ir llamando al componente Product.

<template>
  
</div> </template> import Product from './../components/Product.vue' export default { name: 'home', components: {Product}, computed: { products () { return this.$store.state.products }, }, }

Tenemos la función product() que devuelve los productos almacenados, lo que hacemos es ir iterando los productos y llamar al componente Product

Product

Este componente solo imprime algunos datos de un producto y llama a Vue-router para generar la ruta  hacia el detalle de producto.

<template>
  
{{ product.name }} Ver
</template> export default { name: 'Product', props: ['product'], computed: { url () { return `/products/${this.product.id}` }, }, }

En la parte de script tenemos declarada una función que devuelve URL relativa hacia el producto.

Creando la App de Vue

Tenemos 4 componentes, que en realidad no hacen nada. Tenemos que modificar la App de Vue (App.vue) para indicarle al framework que componentete instanciar.
Por lo que abrimos el fichero App.vue y escribimos

<template>
  
</template> import TopContext from './components/TopContext.vue' export default { name: 'app', components: {TopContext}, }

El componente TopContext no es realmente importante; solo actúa como una cabecera.
La parte clave es el router-view one.

Para que todo termine de funcionar tenemos que hacer que las imágenes se copien, para ello solo tenemos que configurar el
plugin CopyWebpackPlugin que instalamos al principio. Abrimos webpack.config.js y justo antes de ‘resolve’ copiamos

plugins: [
   new CopyWebpackPlugin([{
     from: 'src/static',to:'images'
   }]),
 ],

Todo está listo para empezar a funcionar. Solo tenemos que ejecutar npm run dev y listo se abrirá el navegador y veremos algo como esto así:

Screen Shot 2018-03-17 at 11.01.16.png

El proyecto está alojado en GitHub https://github.com/go-to-next-level/learning-VueJS y como solo tenemos HTML, javascript y CSS podemos alojarlo en github pages en https://go-to-next-level.github.io/learning-VueJS

Conclusiones

Es un primer acercamiento a VueJS. Después de haber leído unos cuantos tutoriales y revisar el típico ejemplo de TodoList no terminaba de quedarme claro como hacer una pequeña app desde 0 con sus dependencias y demás. Además estaba algo abrumado por la cantidad de documentación, librerías, tooling, post… por la mucha información que hay sobre JS y con la cantidad de herramientas que llegan cada día.

Así que la idea era dejar de lado toda la información y ponerme manos a la obra con una pequeña app e ir aprendiendo a medida que iba escribiendo código.

Al final con este pequeño escaparate online, he aprendido a como se estructura el código de una aplicación pequeñita en VueJS, como ir separando responsabilidades por componentes, como usar el store para acceder a los datos y como declarar pequeñas funciones Javascript de “manera moderna”.

Todavía queda mucho por aprender: como hacer test con alguna tool, como darle caña al linter para que el codestyle sea consistente, como sacarle partido al IDE, aprender una serie de herramientas (npm, scripts, linter,…) y descubrir plugins tan útiles como CopyWebpackPlugin.

Anuncios

Comenta la entrada

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

w

Conectando a %s