Vue 3

September 26, 2020

Finalmente, la versión 3 de Vue ha sido liberada y nos da la seguridad de poder utilizar una versión estable en nuestros proyectos que estan en produccón.

Como utilizarla.

Para comenzar a utilizar esta version, debes actualizar tu CLI.

$ npm install -g @vue/cli

y comenzar un nuevo proyecto.

$ vue create new-project

El CLI te preguntara que versión de Vue quieres utilizar, debes estar atento para seleccionar la versión 3 y eso es todo.

$ cd new-project

y

$ npm run serve

Caracteristicas

Global mounting/configuration API change

Tenemos un nuevo cambio y es la manera en que configuramos nuestra App de manera global.

En Vue 2 teniamos esto.

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

Vue.config.ignoredElements = [/^app-/]
Vue.use(/* ... */)
Vue.mixin(/* ... */)
Vue.component(/* ... */)
Vue.directive(/* ... */)

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

Ahora sera algo asi:

import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)

app.config.ignoredElements = [/^app-/]
app.use(/* ... */)
app.mixin(/* ... */)
app.component(/* ... */)
app.directive(/* ... */)

app.mount('#app')

Composition API

Actualmente, cuando estamos agregando logica a un componente utilizamos data, methods, computed, etc. que conocemos como Options API esto trae algunas cosas como no poder tener sugerencias o type checking, ademas, que no es codigo JavaScript per se.

Composition API busca solucionar estos pequeños problemas agregando mecanismos presentes en JavaScript para poder elegir las propiedades de nuestro componente a través de function-based APIs.

Este es un componente en Vue 3.

{% raw %}
<template>
  <button @click="increment">
    Count is: {{ count }}, double is {{ double }}, click to increment.
  </button>
</template>

<script>
import { ref, computed, onMounted } from 'vue'

export default {
  setup() {
    const count = ref(0)
    const double = computed(() => count.value * 2)

    function increment() {
      count.value++
    }

    onMounted(() => console.log('component mounted!'))

    return {
      count,
      double,
      increment
    }
  }
}
</script>
{% endraw %}

Miremos que ahora tenemos que importar las propiedades que vamos a utilizar y usar el metodo setup para devolverlas.

Fragments

En Vue 2 no puedes crear algo asi:

<template>
  <div>Hello</div>
  <div>World</div>
</template>

y la solución era realizar un wrapper que contenga los elementos asi:

<template>
  <div>
    <div>Hello</div>
    <div>World</div>
  </div>
</template>

debido a que los componentes en Vue necesitan ser bindeados en solo un elemento DOM. Ahora ya puedes crear multi-root sin problemas y mantener tu codigo mas limpio.

<template>
  <header>Hello</header>
  <main></main>
  <footer></footer>
</template>

Suspense

Esta sera una forma de suspender la renderización de tu componente hasta que una condicion se cumpla. Es util cuando tenemos que esperar que en un componente se solucionen llamados asincronos que obtienen data de un servicio API.

<template>
  <Suspense>
    <template #default>
      <async-component />
    </template>
    <template #fallback>
      Loading component....
    </template>
  </Suspense>
</template>

<script>
import AsyncComponent from "./AsyncComponent.vue";
export default {
  name: 'RootComponent',
  components: {AsyncComponent},
}
</script>

Multiple v-models

v-model es un herramienta util en los componentes para tener binding en 2 vias pero solo esta permitido su uso a uno por componente. Ahora podras utilizar multiples v-model en tu codigo.

<InviteeForm
  v-model:name="inviteeName"
  v-model:email="inviteeEmail"
/>

Teleport

En algunos escenarios la logica de tu componente genera algo en el template que desde un punto de vista tecnico pertenece a un elemento en otro lugar del DOM.

Pensemos por un momento en un componente <modal-button>.

<body>
  <div style="position: relative;">
    <h3>Tooltips with Vue 3 Teleport</h3>
    <div>
      <modal-button></modal-button>
    </div>
  </div>
</body>

El cual genera un modal.

const app = Vue.createApp({});

app.component('modal-button', {
  template: `
    <button @click="modalOpen = true">
        Open full screen modal!
    </button>

    <div v-if="modalOpen" class="modal">
      <div>
        I'm a modal! 
        <button @click="modalOpen = false">
          Close
        </button>
      </div>
    </div>
  `,
  data() {
    return { 
      modalOpen: false
    }
  }
})

Pero este modal esta anidado dentro de nuestro componente. Teleport provee una manera facil de decirle dentro de que elemento queremos que nuestra pieza de HTML se anide.

app.component('modal-button', {
  template: `
    <button @click="modalOpen = true">
        Open full screen modal! (With teleport!)
    </button>

    <teleport to="body">
      <div v-if="modalOpen" class="modal">
        <div>
          I'm a teleported modal! 
          (My parent is "body")
          <button @click="modalOpen = false">
            Close
          </button>
        </div>
      </div>
    </teleport>
  `,
  data() {
    return { 
      modalOpen: false
    }
  }
})

De esta manera nuestro componente pondra el modal en el body que tiene sentido desde el punto de vista de lo que realiza nuestro componente.

Como migrar nuestra app a Vue 3.

El equipo de Vue a preparado una guia de migración para que hace más claro el proceso para tener nuestra App al dia. La puedes encontrar acá

Si este contenido te parece útil y me quieres ayudar a hacer mas, considera apoyarme en Patreon.

Bueno eso es todo por ahora. Espero sea de utilidad :)