Tag Archives: vue.js

programación

Soporte para TypeScript en Vuejs

Este artículo es una traducción de la documentación oficial. Mis notas estarán debidamente identificadas.

Soporte para TypeScript

A partir de la versión de Vue 2.5.0 en adelante se ha mejorado significativamente las declaraciones de tipos para que operen con el API default basado en objectos. Al mismo tiempo se ha introducido algunos cambios que requieren se realice una debida actualización. Leer el siguiente artículo para más detalles.

Nota: Con esta introducción se reafirma el compromiso del equipo de Vue para mantener un ambiente saludable y ágil a la hora de trabajar con TypeScripte dentro de Vue.

Declaración oficial en los paquetes de NPM

Un sistema de tipado estático puede ayudar a prevenir muchos potenciales errores de runtime, especialmente cuando la aplicación continúa creciendo. Es por esto que Vue ofrece soporte oficial a las declaraciones para tipado estático en TypeScript – no solo para el core de Vue, sino también para las librerías vue-router y vuex.

Dado que estas están publicadas en NPM, y la versión más reciente de TypeScript sabe como resolver las declaraciones de tipo en los paquetes de NPM, esto significa que cuando se instala a través de NPM, no se necesita ninguna herramienta adicional para habilitar TypeScript en Vue.

Nota: Actualmente TypeScript cuenta con una rica colección de tipos gracias al esfuerzo del colectivo Definitely Typed y a la aceptación en general de la comunidad.

Configuración recomendada

// tsconfig.json
{
  "compilerOptions": {
    // esto se alinea con el soporte de Vue en el navegador 
    "target": "es5",
    // permite una inferencia más estricta para las propiedades de datos en `this`
    "strict": true,
    // si se usa webpack 2+ o rollup, para aprovechar el método tree shaking:
    "module": "es2015",
    "moduleResolution": "node"
  }
}

Tenga en cuenta que debe incluir strict: true (o al menos noImpllicitThis: true, que es parte del flag strict) para aprovechar la verificación de tipo para this en los métodos de los componentes, de lo contrario, siempre se tratará como tipo any.

Consulte la documentación de TypeScript para más detalles sobre las opciones del compilador.

Herramientas para desarrollo

Creación de proyectos

Vue CLI 3 puede generar proyectos compatibles con TypeScript. Para comenzar:

# 1. Instalar Vue CLI si aún no lo ha instalado
npm install --global @vue/cli

# 2. Crear un nuevo proyecto, luego seleccione la opción "Manually select features"
vue create mi-proyecto

Soporte en el editor

Para desarrollar aplicaciones usando Vue y TypeScript, se recomienda usar Visual Studio Code, el cual cuenta con soporte nativo para TypeScript. Si usas componentes en modo sigle-file (SFCs), instala la increíble extensión Vetur, que proporciona inferencia de TypeScript dentro del SFC y ofrece una gran cantidad de excelente opciones.

WebStorm también cuenta con soporte nativo para ambos, TypeScript y Vue.

Nota: Vetur es una estupenda herramienta para Vue. Aún si no deseas utilizar TypeScript es una extensión que deberías explorar y añadir al repertorio.

Uso básico

Para que TypeScript infiera adecuadamente los tipos dentro de un componente en Vue, necesitas definir los componentes usando Vue.component o Vue.extend:

import Vue from 'vue'

const Component = Vue.extend({
  // inferencia de tipo habilitada
})

const Component = {
  // aquí NO habrá inferencia de tipos,
  // porque TypeScript no puede inferir que esto son opciones para un componente Vue.
}

Componentes Vue utilizando el modelo Class-Style

Si prefieres una API basada en clases para declarar componentes, puedes usar el decorador oficial vue-class-component:

import Vue from 'vue'
import Component from 'vue-class-component'

// El decorador @Component le indica a la clase que es un componente Vue
@Component({
  // Todas las opciones del componente se definen aquí
  template: '<button @click="onClick">Click!</button>'
})
export default class MyComponent extends Vue {
  // La data inicial puede ser declarada como propiedades de la instancia
  message: string = 'Hello!'

  // Los métodos del componente pueden ser declarado como métodos de la instancia
  onClick (): void {
    window.alert(this.message)
  }
}

Nota: Los decoradores usan una sintaxis especial a través del símbolo @ y se colocan inmediatamente antes de que se decore el código. En la programación orientada a objetos, el patrón decorador (también conocido como Wrapper, nombre alternativo al patrón Adapter) es un patrón de diseño que permite agregar comportamiento a un objeto individual, ya sea estática o dinámicamente, sin afectar el comportamiento de otros objetos de la misma clase. Al momento de redactar este artículo, JavaScript no cuenta con apoyo nativo para decoradores. Existe la propuesta para añadirlo al spec y actualmente se encuentra en el borrador, “Stage 2 Draft / May 23, 2018”.

Aumento de tipos para uso en plug-ins

Los plug-ins pueden agregarse a las propiedades globales/instancia de Vue y a las opciones de los componentes. En estos casos, se necesitan declaraciones de tipo para hacer que los plug-ins se compilen en TypeScript. Afortunadamente, hay una característica de TypeScript para aumentar los tipos existentes llamada aumento de módulos (module augmentation.).

Por ejemplo, para añadir una propiedad a la instancia llamada $myProperty de tipo cadena:

// 1. Asegurate importar 'vue' antes de la declaración aumentada para los tipos
import Vue from 'vue'

// 2. Especifique el archivo con los tipos que desea aumentar 
//    Para el constructor Vue este se encuentra en types/vue.d.ts
declare module 'vue/types/vue' {
  // 3. Utilice la propiedad aumentada en Vue
  interface Vue {
    $myProperty: string
  }
}

Luego de incluir el código anterior como un archivo de declaraciones (algo parecido a my-property.d.ts) en tu proyecto, puedes usar myProperty en la instancia de Vue.

var vm = new Vue()
console.log(vm.$myProperty) // Esto debería compilar sin problema

También puedes declarar propiedades globales adicionales y opciones en los componentes:

import Vue from 'vue'

declare module 'vue/types/vue' {
  // Propiedades Globales pueden ser definidas
  // en la interface `VueConstructor`
  interface VueConstructor {
    $myGlobal: string
  }
}

// ComponentOptions se define en types/options.d.ts
declare module 'vue/types/options' {
  interface ComponentOptions<V extends Vue> {
    myOption?: string
  }
}

Las declaraciones anteriores permiten que el siguiente código pueda ser compilado:

// Propiedad Global
console.log(Vue.$myGlobal)

// Opción adicional
var vm = new Vue({
  myOption: 'Hello'
})

Anotación de tipos para resultados

Debido a la naturaleza circular de los archivos de declaración de Vue, TypeScript puede tener dificultades para inferir los tipos de ciertos métodos. Por esta razón, es posible que deba anotar el tipo del resultado en métodos como render y computed.

import Vue, { VNode } from 'vue'

const Component = Vue.extend({
  data () {
    return {
      msg: 'Hello'
    }
  },
  methods: {
    // necesita una anotación debido al uso de `this` en el resultado
    greet (): string {
      return this.msg + ' world'
    }
  },
  computed: {
    // necesita una anotación
    greeting(): string {
      return this.greet() + '!'
    }
  },
  // `createElement` es inferido pero `render` necesita la anotación
  render (createElement): VNode {
    return createElement('div', this.greeting)
  }
})

Si encuentra que la inferencia de tipo o la resolución del método no funciona, anotar ciertos métodos puede ayudar a resolver estos problemas. Usar la opción --noImplicitAny ayudará a encontrar muchos de estos métodos no anotados.

Nota: Es importante destacar que el uso de tipos no es un requisito para todos los proyectos. Utilizar TypeScript tampoco lo es. Las ventajas son inmensas pero la curva de aprendizaje puede ser atropellada si no se evalúa correctamente al momento de introducirlo en el proyecto o al equipo de trabajo. Tómese su tiempo y no tema en experimentar con esta tecnología.

programación

Los sabores de Vue.js – Standalone y Runtime-only

Anteriormente hemos hablado como instalar Vue.js para crear nuestras aplicaciones web. A continuación, me gustaría tocar el tema de como funcionan los dos sabores disponibles para crear nuestros componentes y por ende nuestra aplicación. En la documentación de Vue.js estos dos sabores son llamados Full distribution y Runtime-only distribution. Por conveniencia vamos a llamar de ahora en adelante a la versión Full, Standalone. Veamos que las hace especial y cómo podemos sacar mejor provecho a la hora de comenzar nuestro proyecto.

Standalone

Esta es la versión que comúnmente utilizamos cuando empezamos con Vue.js. Aquí encontraremos el compilador y el runtime para ejecutar toda la magia de Vue.js. El compilador es el encargado de transformar todo lo que tenemos en nuestro template a funciones render de JavaScript. Este señor se encarga de hacer “todo el trabajo pesado” por nosotros. Cuando utilizas Vue.js desde tu navegador a través de la etiqueta <script>, básicamente estas cargando el compilador y el runtime.

Aquí lo más importante es recordar que el compilador es el encargado de compilar el html o los templates para hacer el rendering al navegador.

Runtime-only

Esta versión no incluye la opción o la habilidad de compilar in-DOM templates como lo hace la versión Standalone. Para poder mostrar html en el navegador debes hacerlo a través de una función de render. A fin de cuentas así es como lo hace la versión Standalone. En realidad, la única tarea que no podemos realizar con el Runtime es la compilación de templates. Todo lo demás es posible – crear instancias, manejar el Virtual DOM, reactividad, ya sabes, todo menos compilar templates.

Hacer render más allá del navegador

Cuando usas la versión Standalone, esta usa los API disponibles a través del navegador para hacer el rendering. La versión Runtime-only no posee esta habilidad. Pero esta carencia le brinda la flexibilidad de poder hacer rendering en ambientes donde no existe la presencia de un navegador, por el ejemplo, en el servidor. No vayas a pensar que la versión Runtime-only es inferior, por el contrario, esto le permite a Vue.js poder ejecutarse en lugares antes no posible. Proyectos como Weex (similar a React Native) y Nuxt.js (Server-Side Rendering usando Vue.js) son posibles gracias al Runtime. Técnicamente el Runtime es el corazón de Vue.js.

Componentes en un archivo único

Continuando con el tema de fortalezas y desventajas, para proyectos pequeños o prototipos rápidos no hay mejor opción que usar la versión Standalone. Ya cuando el proyecto haya crecido suficiente o entiendas que es de una complejidad moderada lo mejor es usar directamente el Runtime. Ahora bien y como ya hemos mencionado, la única mejor manera de usar el Runtime es a través del Vue-cli y usar Single File Components. El problema con los templates es que terminas escribiendo CSS o HTML dentro de un archivo JavaScript, a lo JSX, para arreglar las cosas del HTML en el JavaScript. Aquí es donde Vue.js se destaca de los demás. Los componentes de un solo archivo de Vue es probablemente una gran solución, que te permite poner todo lo relacionado a un componente en un solo lugar resolviendo un gran número de decisiones en torno a la arquitectura de componentes.

Un asunto a considerar es si deseas moverte de usar la versión Standalone a usar solo el Runtime. Ir del código en versión Runtime-only a Standalone es un paseo, técnicamente le has hecho un favor al compilador. Ahora bien, para ir viceversa, de Standalone a Runtime-only tendrás que rescribir todos los componentes para usar funciones render.

Ejemplos

El artículo 7 Ways To Define A Component Template in Vue.js contiene excelentes ejemplos de como crear componentes en Vue.js. No los copiaré aquí pero en resumen los ejemplos de 1-4 usan la versión Standalone y los ejemplos 5-7 usan solo el Runtime.

De no tener claro las ventajas y desventajas de ambos sabores, no dudes en comentarlo.

diseño

Conectar Vue.js a una base de datos

Cuento largo corto es que no es posible ir directamente de Vue.js a la base de datos. Pero en este caso no debemos aceptar un simple “no es posible” como respuesta. Veamos el porque no es posible.

El manejo de la base de datos en una aplicación web no es un problema pertinente o relativo a las funciones de Vue.js, la creación de interfaces de usuario, por lo tanto es un problema que Vue.js no resuelve como framework. Simplemente no es para eso. Para comprender porque no es posible ir de Vue.js directamente a una base de datos vamos a definir que pasos necesitamos para llevar la data de x aplicación hasta la pantalla del usuario. Si usted ya conoce esta historia o está familiarizado con el proceso, no descubrirá nada nuevo aquí, así que le recomiendo continuar navegando por el blog.

Para poder conectarse a una base de datos usted necesita una aplicación del lado del servidor. Por ejemplo, para conectarse a su base de datos Mysql puede utilizar, PHP, Node.js o .Net Core. Todo esto puede estar instalado en un servidor o en varios. Con estas herramientas crearas los que se conoce como un API. El API se encargará de exponer la data. Ya que Vue.js es una aplicación del lado del cliente (vive en su navegador) y Mysql es una aplicación del lado del servidor usted necesitará de un mecanismo del lado del servidor para poderse conectar a su base de datos a través del API creado. Este mecanismo puede ser a través de llamadas REST usando como canal el protocolo HTTP. En Vue.js puedes manejar y/o consumir llamadas tipo REST pero lo que necesitas es poder crear estos recursos (API) para que Vue.js o cualquier herramienta pueda consumirlos.

En resumen, Vue.js se ejecuta en la parte del cliente, dentro del navegador (front-end). La parte de la base de datos se ejecuta en el servidor (back-end). Desde Vue.js puedes accesar los datos de la base de datos usando como mecanismo el protocolo HTTP. Para esto creas llamadas usando Ajax desde el cliente y así puedes consumir los datos de la base de datos a través de un API. Recuerda, estos datos se manejan en el servidor a través de un HTTP server que expone la data como un API al cliente. Este API se encarga de manejar la seguridad y todo lo necesario para mostrar la data de forma accesible al cliente en este caso Vue.js. Pero es lo mismo para React, Angular, Aurelia, etc.

programación

Componentes Vue.js en español

Vayamos rápido al grano sobre el tema de componentes en Vue.js. Por ahora, sólo necesitas saber que todos los componentes en Vue son esencialmente una extensión a la instancia de Vue.

// Instancia Vue
new Vue({
  el: '#some-element',
  // options
})

Utilizando el entorno ofrecido por la herramienta vue-cli, vamos a utilizar los archivos iniciales para ver como trabajamos con los components. Veamos el siguiente ejemplo:

import Vue from 'vue'
import App from './App.vue'

// Extendemos las instancia para crear los componentes
Vue.component('comp1', {
  template:'<div>Component 1</div>' 
}) 

Vue.component('comp2', { 
  template:'<div>Component 2</div>' 
}) 

Vue.component('comp3', { 
  template:'<div>Component 3</div>' 
}) 

// Instancia de Vue 
new Vue({ 
  el: '#app', 
  render: h => h(App) 
})

Continuar la lectura…

programación

Construir un ambiente de desarrollo para Vue.js usando Webpack

Después de haber escrito sobre lo básico de Vue.js es momento de pasar al próximo nivel, Vue.js usando Webpack. La idea este “próximo nivel” es poder tener un ambiente relativamente completo para desarrollar nuestro front-end.

Vue ha desarrollado una herramienta increíblemente práctica para este propósito. La herramienta es conocida como vue-cli y contiene todo lo necesario para arrancar el ambiente de desarrollo. Lo bueno de utilizar esta herramienta es que provee una manera oficial y opinionada de empezar un proyecto. Además provee espacio para adaptarlo a nuestra necesidades y gustos.

Para comenzar a utilizar vue-cli debes tener: Node.js (>=4.x, 6.x siendo preferido) y Git. En cuanto a npm una recomendación es tener npm >= 3.x.

Instalamos de la siguiente manera:

$ npm install -g vue-cli

Actualmente los templates oficiales disponible son:

  • webpack
  • webpack-simple
  • browserify
  • browserify-simple
  • simple

Si deseas utilizar vue-cli para trabajar con tu propio template los puedes hacer fácilmente. La documentación oficial lo explica con lujo de detalle.

Para propósitos de este tutorial y porque es el template que más utilizo estaremos trabajando con webpack. Esta versión es bien completa e incluye todo lo que necesitamos: Webpack Dev Server, Babel setup, Hot Reloading, Unit Testing, etc.

Ya que hemos instalado vue-cli, vamos a utilizarlo para crear nuestro proyecto y de una vez procederemos a instalar las dependencias.

$ vue init webpack my-project

$ cd my-project

$ npm install

Ya con todo en su lugar vamos a inicial el proyecto.

$ npm run dev

Conclusión

Es hora de repasar que tenemos hasta el momento. Hemos creado un proyecto a través de la herramienta vue-cli. Esta herramienta utiliza Webpack para manejar todo el ambiente de desarrollo de Vue. Nada “fancy” por el momento pero si analizamos todo lo que tenemos con tan solo usar vue-cli, comprenderemos el gran ahorro en tiempo y stress que esta simple herramienta nos provee.

programación

Primeros pasos usando Vue.js

Entonces un día decidí que solo aprenderé solo un, a lo máximo dos, Javascript frameworks. Así fue que me decidí por Vue.js. Y es que en estos días abundan miles de frameworks que de una forma u otra “te ayudan” a se ser más productivos. Este es el caso de Vue.js. Realmente se ha convertido en una herramienta que me hace sentir productivo. Llevo tiempo aprendiendo sobre el framework y me gustaría compartir lo divertido que ha sido utilizarlo.

Voy a utilizar como ejemplo un webapp que en resumen, se encarga de leer la lectura más reciente de los depósitos de agua en Puerto Rico, país donde resido. Hace un año atrás, nuestra isla sufrió una fuerte sequía. Durante ese proceso el tema de monitorear los niveles de las reservas de agua se convirtió en una costumbre cotidiana. En el repositorio de Github hablo un poco más sobre el asunto. Así que vayamos al grano.

¿Por qué Vue.js?

Una de las razones principales que me motivó a tratar esta librería, es la forma en que implementa el tema de reactividad en un webapp. Digamos que tenemos un objecto en Javascript definido de la siguiente manera:

var object = {
  message: 'Hello world!'
}

En el HTML tenemos un template de tipo handlebars:

<div id="example">
 {{ message }}
</div>

Con Vue.js solo decimos a donde miramos en el HTML y que objeto le voy a pegar y la librería posee toda la magia (lógica) para hacer nuestros dos elementos reactivos, two way binding sin esfuerzo alguno.

new Vue({
 el: '#example',
 data: object
})

Instalación de Vue.js

Vue.js es prácticamente compatible con cualquier browser moderno. Para este proyecto he usado la versión accesible a través de CDN.

<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/vue/1.0.16/vue.js"></script>

Otra manera de utilizarla, es descargándola directamente a tu folder de trabajo. Bower es tremenda opción para esta configuración. Es altamente recomendable utilizar la versión de desarrollo (development version) y no la comprimida que es recomendable para producción. Esto debido a que la versión de desarrollo ofrece varios mecanismos que ayudan a depurar mucho más fácil el código. Para activar este modo solo necesitas añadir la siguiente declaración:

Vue.config.debug = true

Vue Instance

Antes de continuar con la descripción de la instancia de Vue, vamos a repasar lo que estamos tratando de construir. Este webapp necesita consumir data de un repositorio en Firebase. No tocaré el tema de Firebase en este momento, lo único que necesitamos saber es que desde Firebase vamos a recibir un objecto en formato JSON para poder consumirlo en el cliente. Cada vez que este objeto se actualice, Vue.js se encargará de sincronizar toda esta serie de eventos para poder ver los cambios de manera instantánea en nuestro browser. Solo necesitaremos un archivo index.html y un archivo main.js. La instancia la creamos de la siguiente forma en el archivo main.js:

var vm = new Vue({
 // opciones
})

La instancia de Vue es esencialmente la parte viewmodel del patrón MVVM, de ahí el nombre de la variable vm. Cuando creamos una instancia de Vue, necesitamos pasar un objeto de opciones que puede contener configuraciones para los datos, templates, elementos para montar, métodos, lifecycle callbacks etc. Para que nuestra instancia pueda comenzar a trabajar vamos incluir los siguientes dos métodos:

var vm = new Vue({
  el: #app",
  data: embalses
 // más opciones
})

El primero método es el nombre del tag que usaremos para mostrar la data. El método data es el objeto que contiene la información que mostraremos en el documento html. Con esto es suficiente para mostrar nuestra información. Veamos como podemos manejar esta data.

Directivas en Vue.js

v-for

Vue.js posee varias directivas que ayudan a modificar elementos del DOM. Una directiva es un marcador que se le coloca a un elemento del DOM para alterar su comportamiento o incluso para transformar elementos que se encuentren debajo de este elemento. Este marcador puede ser un  atributo, el nombre del elemento, un comentario o una clase CSS. En nuestro ejemplo he usado la directiva v-for para generar y presentar los elementos que se encuentran definidos como un arreglo en el objeto data de la instancia.

<div v-for="value in embalses">
  <div v-for="item in value">
    <div class="row">
      <div>
        <p>{{ item.city }}</p>
        <h3>{{ item.name }}</h3>
      </div>
      <div>
        <h2>{{ item.currentLevel}}</h2> 
        <p>{{ item.currentLevelTime }}</p>
      </div>
    </div>
  </div>
</div>

Debido a la estructura del objeto embalses he tenido que recurrir a utilizar un for anidado (nested for) para obtener la data de los embalses.

v-on

Esta directiva permite conectar un detector de eventos a los elementos del DOM. El ejemplo más sencillo es el evento click. Esta directiva la he utilizado para crear una serie de botones para ordenar la data por diferentes criterios.

<button type="button" v-on:click="sortBy('city')">Pueblo</button>
<button type="button" v-on:click="sortBy('currentLevel')">Nivel</button>

Métodos y eventos

En Vue.js conectar a un elemento del DOM un detector de eventos es asunto trivial. Veamos como lo hacemos para el clásico evento de onclick. De esta manera utilizaremos el evento para invocar un método que contenga la lógica para reorganizar nuestra data. En Vue.js este método es parte de la instancia. O sea que el método termina siendo una opción mas que podemos configurar fácilmente. Digamos que nuestro método se llama sortBy:

var vm = new Vue({
  el: '#app',
  data: {
    embalses,
    order: 1,
    sortKey: 'city'
  },
  methods: {
    sortBy: function(key){ 
      this.sortKey = key;
      this.order = this.order * -1;
    }
  }
})

Ahora veamos como pegamos todo esto a través de la opción de filtros. Una directiva que nos facilita completar la función de ordenar los elementos es la directiva de orderBy.

<div v-for="item in value | orderBy sortKey order">

Usando el filtro orderBy de Vue.js junto al método creado de sortBy podemos usar parte de la configuración de la instancia (sortKey, order) para organizar los elementos del objeto data.

Producto final

See the Pen Order by in Vue.js by Jaime Olmo (@jamespr) on CodePen.4734

¿Qué es lo próximo?

Hemos tocado solo lo básico del tema. El próximo paso será cómo crear componentes reactivos que es donde realmente Vue.js se destaca con su sencillez y simpleza para crear interfaces de usuarios modernas para la plataforma Web. Aún queda mucho por aprender.