Introduction to Composition API A new and different way to write your Vue apps. Introduction to Composition API • Vue Amsterdam 2021 • @bencodezen
A presentation at Vue.js Amsterdam in February 2021 in by Ben Hong
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