Introduction to Composition API A new and different way to write your Vue apps. Introduction to Composition API • Vue Amsterdam 2021 • @bencodezen

Senior DX Engineer @ Netlify A little about me Vue.js Core Team Vue Mastery Instructor Google Developer Expert Introduction to Composition API • Vue Amsterdam 2021 • @bencodezen

What is the Composition API? Introduction to Composition API • Vue Amsterdam 2021 • @bencodezen

At its core, the Composition API is another way to build Vue.js apps and organize your code. Introduction to Composition API • Vue Amsterdam 2021 • @bencodezen

At its core, the Composition API is another way to build Vue.js apps and organize your code. Introduction to Composition API • Vue Amsterdam 2021 • @bencodezen

The Composition API does not replace the Options API. Introduction to Composition API • Vue Amsterdam 2021 • @bencodezen

Let’s ReVue: The Options API Introduction to Composition API • Vue Amsterdam 2021 • @bencodezen

simple-option-api.vue <script> export default { data: () => ({ count: 0 }), computed: { doubleCount() { return this.count * 2 } }, methods: { incrementCount() { this.count++ } } } </script> <template> <p>{{ count }}</p> </template>

simple-option-api.vue <script> export default { data: () => ({ count: 0 }), computed: { doubleCount() { return this.count * 2 } }, methods: { incrementCount() { this.count++ } } } </script> <template> <p>{{ count }}</p> </template>

simple-option-api.vue <script> export default { data: () => ({ count: 0 }), computed: { doubleCount() { return this.count * 2 } }, methods: { incrementCount() { this.count++ } } } </script> <template> <p>{{ count }}</p> </template>

simple-option-api.vue <script> export default { data: () => ({ count: 0 }), computed: { doubleCount() { return this.count * 2 } }, methods: { incrementCount() { this.count++ } } } </script> simple-composition-api.vue <script> import { computed, ref } from ‘vue’ export default { setup() { const count = ref(0) const doubleCount = computed(() => { return count.value * 2 }) const incrementCount = () => { count.value += 1 } } return { count, doubleCount, incrementCount } } </script> <template> <p>{{ count }}</p> </template> <template> <p>{{ count }}</p> </template>

simple-option-api.vue <script> export default { data: () => ({ count: 0 }), computed: { doubleCount() { return this.count * 2 } }, methods: { incrementCount() { this.count++ } } } </script> simple-composition-api.vue <script> import { computed, ref } from ‘vue’ export default { setup() { const count = ref(0) const doubleCount = computed(() => { return count.value * 2 }) const incrementCount = () => { count.value += 1 } } return { count, doubleCount, incrementCount } } </script> <template> <p>{{ count }}</p> </template> <template> <p>{{ count }}</p> </template>

simple-option-api.vue <script> export default { data: () => ({ count: 0 }), computed: { doubleCount() { return this.count * 2 } }, methods: { incrementCount() { this.count++ } } } </script> simple-composition-api.vue <script> import { computed, ref } from ‘vue’ export default { setup() { const count = ref(0) const doubleCount = computed(() => { return count.value * 2 }) const incrementCount = () => { count.value += 1 } } return { count, doubleCount, incrementCount } } </script> <template> <p>{{ count }}</p> </template> <template> <p>{{ count }}</p> </template>

simple-option-api.vue <script> export default { data: () => ({ count: 0 }), computed: { doubleCount() { return this.count * 2 } }, methods: { incrementCount() { this.count++ } } } </script> simple-composition-api.vue <script> import { computed, ref } from ‘vue’ export default { setup() { const count = ref(0) const doubleCount = computed(() => { return count.value * 2 }) const incrementCount = () => { count.value += 1 } } return { count, doubleCount, incrementCount } } </script> <template> <p>{{ count }}</p> </template> <template> <p>{{ count }}</p> </template>

simple-option-api.vue <script> export default { data: () => ({ count: 0 }), computed: { doubleCount() { return this.count * 2 } }, methods: { incrementCount() { this.count++ } } } </script> simple-composition-api.vue <script> import { computed, ref } from ‘vue’ export default { setup() { const count = ref(0) const doubleCount = computed(() => { return count.value * 2 }) const incrementCount = () => { count.value += 1 } } return { count, doubleCount, incrementCount } } </script> <template> <p>{{ count }}</p> </template> <template> <p>{{ count }}</p> </template>

simple-option-api.vue <script> export default { data: () => ({ count: 0 }), computed: { doubleCount() { return this.count * 2 } }, methods: { incrementCount() { this.count++ } } } </script> simple-composition-api.vue <script> import { computed, ref } from ‘vue’ export default { setup() { const count = ref(0) const doubleCount = computed(() => { return count.value * 2 }) const incrementCount = () => { count.value += 1 } } return { count, doubleCount, incrementCount } } </script> <template> <p>{{ count }}</p> </template> <template> <p>{{ count }}</p> </template>

simple-composition-api.vue

<script> export default { setup() { const count = 0 } return { count } } </script>

simple-composition-api.vue

<script> export default { setup() { const count = 0 } return { count } } </script>

simple-composition-api.vue

<script> export default { setup(props, context) { const count = 0 } return { count } } </script>

simple-composition-api.vue

<script> export default { setup(props, ctx) { const count = 0 } return { count } } </script>

simple-composition-api.vue

<script> export default { setup(props, { attrs, slots, emit }) { const count = 0 } return { count } } </script>

simple-composition-api.vue

<script> export default { setup(props, ctx) { const count = 0 } return { count } } </script>

simple-composition-api.vue

<script> export default { setup(props, ctx) { const count = 0 } return { count } } </script>

simple-composition-api.vue

<script> export default { setup(props, ctx) { const count = 0 } return { count } } </script>

simple-composition-api.vue

<script> export default { setup(props, ctx) { const count = 0 } return { count } } </script>

Reactive Data in Composition API

reactive-in—composition-api.vue

<script> export default { data() { return { count: 0 } } } </script>

<template> <p>{{ count }}</p> </template>

reactive-in—composition-api.vue

<script> export default { setup() { const count = 0 } return { count } } </script>

<template> <p>{{ count }}</p> </template>

ref Launching with Composition API Netlify DevEx Team December 2020

reactive-in—composition-api.vue

<script> export default { setup() { const count = 0 } return { count } } </script>

<template> <p>{{ count }}</p> </template>

reactive-in—composition-api.vue

<script> import { ref } from ‘vue’ export default { setup() { const count = 0 } return { count } } </script>

<template> <p>{{ count }}</p> </template>

reactive-in—composition-api.vue

<script> import { ref } from ‘vue’ export default { setup() { const count = ref(0) } return { count } } </script>

<template> <p>{{ count }}</p> </template>

reactive-in—composition-api.vue

<script> import { ref } from ‘vue’ export default { setup() { const count = ref(0) } return { count } } </script>

<template> <p>{{ count }}</p> </template>

reactive-in—composition-api.vue

<script> import { ref } from ‘vue’ export default { setup() { const count = ref(0) const incrementCount = () => { } } return { count } } </script> <template> <p>{{ count }}</p>

reactive-in—composition-api.vue

<script> import { ref } from ‘vue’ export default { setup() { const count = ref(0) const incrementCount = () => { count += 1 } } return { count } } </script> <template> <p>{{ count }}</p>

reactive-in—composition-api.vue

<script> import { ref } from ‘vue’ export default { setup() { const count = ref(0) const incrementCount = () => { count += 1 } } return { count } } </script> <template> <p>{{ count }}</p>

reactive-in—composition-api.vue

<script> import { ref } from ‘vue’ export default { setup() { const count = ref(0) const incrementCount = () => { count += 1 } } return { count } } </script> <template> <p>{{ count }}</p>

reactive-in—composition-api.vue

<script> import { ref } from ‘vue’ export default { setup() { const count = ref(0) const incrementCount = () => { this.count += 1 } } return { count } } </script> <template> <p>{{ count }}</p>

reactive-in—composition-api.vue

<script> import { ref } from ‘vue’ export default { setup() { const count = ref(0) const incrementCount = () => { this.count += 1 } } return { count } } </script> <template> <p>{{ count }}</p>

reactive-in—composition-api.vue

<script> import { ref } from ‘vue’ export default { setup() { const count = ref(0) const incrementCount = () => { count += 1 } } return { count } } </script> <template> <p>{{ count }}</p>

reactive-in—composition-api.vue

<script> import { ref } from ‘vue’ export default { setup() { const count = ref(0) const incrementCount = () => { count.value += 1 } } return { count } } </script> <template> <p>{{ count }}</p>

reactive Launching with Composition API Netlify DevEx Team December 2020

reactive-in—composition-api.vue

<script> export default { setup() { const count = 0 } return { count } } </script>

<template> <p>{{ count }}</p> </template>

reactive-in—composition-api.vue

<script> import { reactive } from ‘vue’ export default { setup() { const count = 0 } return { count } } </script>

<template> <p>{{ count }}</p> </template>

reactive-in—composition-api.vue

<script> import { reactive } from ‘vue’ export default { setup() { const count = 0 const state = reactive({}) } return { count } } </script> <template> <p>{{ count }}</p> </template>

reactive-in—composition-api.vue

<script> import { reactive } from ‘vue’ export default { setup() { const count = 0 const state = reactive({}) } return { count, state } } </script> <template> <p>{{ count }}</p> </template>

reactive-in—composition-api.vue

<script> import { reactive } from ‘vue’ export default { setup() { const count = 0 const state = reactive({ }) } return { count, state } } </script> <template>

reactive-in—composition-api.vue

<script> import { reactive } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) } return { count, state } } </script> <template> <p>{{ count }}</p> </template>

reactive-in—composition-api.vue

<script> import { reactive } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) } return { state } } </script> <template> <p>{{ count }}</p> </template>

reactive-in—composition-api.vue

<script> import { reactive } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) } return { state } } </script> <template> <p>{{ state.count }}</p> </template>

reactive-in—composition-api.vue

<script> import { reactive } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) const incrementCount = () => { count.value += 1 } } return { state } } </script>

reactive-in—composition-api.vue

<script> import { reactive } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) const incrementCount = () => { count += 1 } } return { state } } </script>

reactive-in—composition-api.vue

<script> import { reactive } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) const incrementCount = () => { state.count += 1 } } return { state } } </script>

reactive-in—composition-api.vue

<script> import { reactive } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) } return { state } } </script> <template> <p>{{ state.count }}</p> </template>

toRefs Launching with Composition API Netlify DevEx Team December 2020

reactive-in—composition-api.vue

<script> import { reactive } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) } return { state } } </script> <template> <p>{{ state.count }}</p> </template>

reactive-in—composition-api.vue

<script> import { reactive } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) } return { …state } } </script> <template> <p>{{ state.count }}</p> </template>

reactive-in—composition-api.vue

<script> import { reactive } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) } return { …state } } </script> <template> <p>{{ count }}</p> </template>

reactive-in—composition-api.vue

<script> import { reactive } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) } return { …state } } </script> <template> <p>{{ count }}</p> </template>

reactive-in—composition-api.vue

<script> import { reactive } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) } return { …state } } </script> <template> <p>{{ count }}</p> </template>

reactive-in—composition-api.vue

<script> import { reactive, toRefs } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) } return { …state } } </script> <template> <p>{{ count }}</p> </template>

reactive-in—composition-api.vue

<script> import { reactive, toRefs } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) } return { …toRefs(state) } } </script> <template> <p>{{ count }}</p> </template>

reactive-in—composition-api.vue

<script> import { reactive, toRefs } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) } return { …toRefs(state) } } </script> <template> <p>{{ count }}</p> </template>

Computed Properties Introduction to Composition API • Vue Amsterdam 2021 • @bencodezen

computed-in-composition-api.vue

<script> import { reactive, toRefs } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) } return { …toRefs(state) } } </script>

computed-in-composition-api.vue

<script> import { reactive, toRefs } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) const doubleCount = state.count * 2 } return { …toRefs(state) } } </script>

computed-in-composition-api.vue

<script> import { reactive, toRefs } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) const doubleCount = state.count * 2 } return { …toRefs(state), doubleCount } } </script>

computed-in-composition-api.vue

<script> import { reactive, toRefs } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) const doubleCount = state.count * 2 } return { …toRefs(state), doubleCount } } </script>

computed-in-composition-api.vue

<script> import { reactive, toRefs } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) const doubleCount = state.count * 2 } return { …toRefs(state), doubleCount } } </script>

computed-in-composition-api.vue

<script> import { reactive, toRefs } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) const doubleCount = state.count * 2 } return { …toRefs(state), doubleCount } } </script>

computed-in-composition-api.vue

<script> import { reactive, toRefs } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) const doubleCount = state.count * 2 } return { …toRefs(state), doubleCount } } </script>

computed-in-composition-api.vue

<script> import { reactive, toRefs } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) const doubleCount = state.count * 2 } return { …toRefs(state), doubleCount } } </script>

computed-in-composition-api.vue

<script> import { computed, reactive, toRefs } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) const doubleCount = state.count * 2 } return { …toRefs(state), doubleCount } } </script>

computed-in-composition-api.vue

<script> import { computed, reactive, toRefs } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) const doubleCount = computed(() => { return state.count * 2 }) } } return { …toRefs(state), doubleCount }

computed-in-composition-api.vue

<script> import { computed, reactive, toRefs } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) const doubleCount = computed(() => { return state.count * 2 }) } } return { …toRefs(state), doubleCount }

computed-in-composition-api.vue

<script> import { computed, reactive, toRefs } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) const doubleCount = computed(() => { return state.count * 2 }) } } return { …toRefs(state), doubleCount }

computed-in-composition-api.vue

<script> import { computed, reactive, toRefs } from ‘vue’ export default { setup() { const state = reactive({ count: 0, doubleCount: computed(() => { return state.count * 2 }) }) } return { …toRefs(state), doubleCount } } </script>

computed-in-composition-api.vue

<script> import { computed, reactive, toRefs } from ‘vue’ export default { setup() { const state = reactive({ count: 0, doubleCount: computed(() => { return state.count * 2 }) }) } return { …toRefs(state) } } </script>

computed-in-composition-api.vue

<script> import { computed, reactive, toRefs } from ‘vue’ export default { setup() { const state = reactive({ count: 0, doubleCount: computed(() => { return state.count * 2 }) }) } return { …toRefs(state) } } </script>

Methods Introduction to Composition API • Vue Amsterdam 2021 • @bencodezen

methods-in-composition-api.vue

<script> import { reactive } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) } return { state } } </script>

methods-in-composition-api.vue

<script> import { reactive } from ‘vue’ export default { setup() { const state = reactive({ count: 0 }) const incrementCount = () => { state.count += 1 } } return { state } } </script>

setup() { const state = reactive({ count: 0 }) const incrementCount = () => { state.count += 1 } } return { state } } </script> <template> <p>{{ state.count }}</p> </template>

setup() { const state = reactive({ count: 0 }) const incrementCount = () => { state.count += 1 } } return { state, incrementCount } } </script> <template> <p>{{ state.count }}</p> </template>

setup() { const state = reactive({ count: 0 }) const incrementCount = () => { state.count += 1 } } return { state, incrementCount } } </script> <template> <button @click=”incrementCount”> Increment Count: {{ count }} </button> </template>

setup() { const state = reactive({ count: 0 }) const incrementCount = () => { state.count += 1 } } return { state, incrementCount } } </script> <template> <button @click=”incrementCount”> Increment Count: {{ count }} </button> </template>

That’s the basics!

Is there more? • • • • Lifecycle Hooks Watch Modules And many more APIs…

Next Steps

Can be more verbose and have less structure compared to Options API More JavaScript knowledge is needed Trade-offs Deeper understanding of Vue.js is required to use it Architectural decisions are up to you Introduction to Composition API • Vue Amsterdam 2021 • @bencodezen

You may be tempted to rewrite your entire app in Composition API. Introduction to Composition API • Vue Amsterdam 2021 • @bencodezen

You may be tempted to rewrite your entire app in Composition API. Please don’t. Introduction to Composition API • Vue Amsterdam 2021 • @bencodezen

The Composition API is a powerful technique to understand and have in your skillset, but remember that at the end of the day. Introduction to Composition API • Vue Amsterdam 2021 • @bencodezen

The Composition API is a powerful technique to understand and have in your skillset, but remember that at the end of the day. All code is compromise. Introduction to Composition API • Vue Amsterdam 2021 • @bencodezen

“But I want more Composition API!” Introduction to Composition API • Vue Amsterdam 2021 • @bencodezen

Section title goes here and wraps nicely Introduction to Composition API • Vue Amsterdam 2021 • @bencodezen

Section title goes here and wraps nicely Introduction to Composition API • Vue Amsterdam 2021 • @bencodezen

Section title goes here and wraps nicely Introduction to Composition API • Vue Amsterdam 2021 • @bencodezen

Thank you! Find me at @bencodezen GitHub.com/bencodezen Twitter.com/bencodezen YouTube.com/bencodezen Introduction to Composition API • Vue Amsterdam 2021 • @bencodezen