ianaya89

Vue 3 y Composition API

A patear el tablero

Vue 3 y Composition API

πŸŽ―πŸ–– 3️⃣

🐦 @ianaya89


πŸ‡¦πŸ‡· Nacho Anaya

🐦 @ianaya89

right


🚨


πŸ”œ vue-next


🀏 πŸƒβ€β™‚οΈ 🀯

Smaller + Faster + Easier


0️⃣ Re-escrito


πŸ“ Simple y ExplΓ­cito


πŸ“Š Performance

~120% mas rΓ‘pido

right fit


πŸ’ Monorepo

inline


🎁 Paquetes Individuales

inline


<br> # βž• Extensible

right inline 50%inline 50%left inline 40%


<br> # 🌳 Tree-Shakeable

Global API

right inline 12%left inline 50%


πŸ“‰ 10 KB gzipped

v2.x ~20 KB


<br> # πŸ”© TypeScript

inline 100%


🌎 Global Mounting

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

const app = createApp(App)

app.use(/* ... */)
app.mixin(/* ... */)
app.component(/* ... */)
app.directive(/* ... */)

app.mount('#app')

☒️ Reactivity Engine

  • πŸ”š Object.defineProperty()
  • πŸ”œ Proxy

☒️ πŸ”™ Antes (2.x)

<script>
	export default {
	  data () {
	    return {
		    object: { name: 'Nacho' },
		    array: ['string']
	    }
	  },
	  
	  created () {
		  this.$set(this.object, 'lastName', 'Anaya')
		  this.$delete(this.object, 'lastName')
		  this.$set(this.array, 1, 'new string')
	  }
	}
</script>

☒️ πŸ”™ Antes (2.x)

<script>
	export default {
	  data () {
	    return {
		    object: { name: 'Nacho' },
		    array: ['string']
	    }
	  },
	  
	  created () {
		  this.$set(this.object, 'lastName', 'Anaya')
		  this.$delete(this.object, 'lastName')
		  this.$set(this.array, 1, 'new string')
	  }
	}
</script>

☒️ πŸ”œ Ahora (3.x)

<script>
	export default {
	  data () {
	    return {
		    object: { name: 'Nacho' },
		    array: ['string']
	    }
	  },
	  
	  created () {
			this.object.lastName = 'Anaya'
			delete this.object.lastName
			this.array[1] = 'new string'
	  }
	}
</script>

☒️ πŸ”œ Ahora (3.x)

πŸ’€ "Reactivity Caveats"


☒️ πŸ”œ Ahora (3.x)

Map - Set - WeakMap - WeakSet


πŸ”— Multiples v-model

<LoginForm
	v-model:email="email"
	v-model:password="password"
	v-model:rememberMe="rememberMe"
/>

🍰 Fragments

πŸ•Έ Multiples Root Elements

<template>
	<div>...</div>
	<div>...</div>
</template>

πŸ•³ Portals

<Portal target="#my-portal" />


πŸ•³ Portals

<!-- App.vue -->
<template>
   <main>
      <router-view />
      <div id="my-portal"></div>
   </main>
</template>

πŸ•³ Portals

<!-- Other.vue -->
<template>
   <main>
      <h1>Hola!</h1>
      
      <Portal target="#my-portal">
	      <p>Este es el contenido del Portal<\p>
      </Portal>
   </main>
</template>

πŸ”ͺ Suspense

<Suspense>
  <template #default>
     <UserList />
  <template>
  <template #fallback>
	  <p>Loading...</p>
  </template>
</Suspense>

πŸ›£



πŸ•ΊπŸΏπŸ•ΊπŸΏπŸ•ΊπŸΏπŸ•ΊπŸΏ ⚰️ Class API

inline


inline


πŸ•ΊπŸΏπŸ•ΊπŸΏπŸ•ΊπŸΏπŸ•ΊπŸΏ ⚰️ Function API

inline


inline


Ξ» πŸ“¦ Composition API

inline


πŸ“¦

πŸ“¦πŸ“¦

πŸ“¦πŸ“¦πŸ“¦

Ζ› Composicion flexible basada en funciones


πŸ‘€ Reactivity API


πŸ‘€ Reactivity API

import { ref } from 'vue'

const num = ref(0)
console.log(num.value)

const increment = () => (num.value += 1)
document.body.addEventListener('click', increment)

πŸ‘€ Reactivity API

import { ref, watchEffect } from 'vue'

const num = ref(0)

const increment = () => (num.value += 1)
document.body.addEventListener('click', increment)

watchEffect(() => (
	document.body.innerHTML = `num is ${num.value}`
))

πŸ‘€ Reactivity API

import { reactive, computed } from 'vue'

const state = reactive({ 
	count: 1,
	double: computed(() => state.count * 2)
})

πŸ‘‹ Hello Vue3!

setup(props, context)


<template>
	<h1>Num is {{ num }}</h1>
  <button @click="increment">+</button>
</template>

<script>
import { ref } from 'vue'

export default {
  setup() {
    const num = ref(0)
    const increment = () => (num.value += 1)


    return { num, increment }
  }
}
</script>

πŸ‘‹ Hello Vue3!

<template>

  <div>

    <child-component :name="Nacho" />

  </div>

</template>

πŸ‘‹ Hello Vue3!

<template>
  <div>
    <h1>Hola {{ name }}!</h1>
  </div>
</template>

<script>
export default {
  props: { name: String },
  
  setup(props, context) {
    const { name } = props
    
    return { name }
  }
}
</script>

πŸ‘‹ Hello Vue3!

export default {  
  setup(props, context) {
    console.log(props)
    
    context.attrs
    context.slots
    context.refs
    context.emit
    context.parent
    context.root
  }
}

♻️ Dynamic Lifecycle Injection


♻️ Dynamic Lifecycle Injection

import { onMounted, onUpdated } from 'vue'

export default {

	setup () {
	  onMounted(() => console.log('Mounted'))
	  
  	  onUpdated(() => console.log('Updated'))
	}
	
}

♻️ Dynamic Lifecycle Injection

import { onMounted } from 'vue'

export default {

  setup () {
  
    // attachar un hook para otro componente
    onMounted(() => console.log('Mounted...'), otherComponent)	  
  }
  
}

πŸ™‡β€β™‚οΈ MotivaciΓ³n

  • Escalabilidad
  • Inferencia de Tipos
  • Organizacion
  • Performance
  • πŸ‘‰Logic CompositionπŸ‘ˆ

πŸ“¦πŸ“¦πŸ“¦ Logic Composition


πŸ“œ Patrones Actuales

  • Mixins
  • HOC
  • Renderless Components

πŸ“¦ Logic Composition

import { ref, onMounted, onUnmounted } from 'vue'

export default function useMousePosition() {
	const x = ref(0)
	const y = ref(0)
  
  function updatePosition(e) {
    x.value = e.pageX
    y.value = e.pageY
  }

  onMounted(() => window.addEventListener('mousemove', updatePosition))
  
  onUnmounted(() => window.removeEventListener('mousemove', updatePosition))
  
  return { x, y }
}

πŸ“¦ Logic Composition

<template>
  <div>Position {{ x }} {{ y }}</div>
</template>

<script>
import useMousePosition from './useMousePosition'
import useOtherLogic from './useOtherLogic'

export default {
  setup() {
    const { x, y } = useMousePosition()
    const other  = useOtherLogic()
    
    return { x, y, other }
  }
}
</script>

πŸ™€ SE ROMPE TODO!




🍾 NO SE ROMPE NADA!


Composition API

🀝

Options API


βœ… Composition API

  • Aplicaciones / componentes grandes
  • Equipos grandes
  • Compartir / reusar codigo
  • Soporte TS

πŸ‘¨β€πŸ’» Como usarlo?

<br>
$ vue create my-app
$ vue add vue-next


πŸ“Ί Demo


πŸš€ github.com/vuejs/vue-next


πŸ‘‰ vue-composition-api-rfc.netlify.com


πŸ“’ github.com/vuejs/rfcs


Nacho: "When Vue 3.0 will be ready?"

Evan: "When it’s ready"

right


πŸ“… Q4 2019 (?)


πŸ“… Q4 2019 πŸ‘‰ Alpha


πŸ“… Q1 2020 πŸ‘‰ Beta


πŸ“… Q2 2020 πŸ‘‰ RC (?)

right


Gracias! πŸ‘

🐦 @ianaya89


πŸ‘‡ Preguntas?

🐦 @ianaya89


πŸ‘¨β€πŸ« Capacitaciones Avanzadas

🐦 @ianaya89