Create Vue 3 Apps with the Composition API — Lifecycle Hooks and Refs

John Au-Yeung - Jan 19 '21 - - Dev Community

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

Subscribe to my email list now at http://jauyeung.net/subscribe/

It lets us extract logic easily an not have to worry about the value of this in our code.

It also works better with TypeScript because the value of this no longer has to be typed.

In this article, we’ll look at how to create Vue 3 apps with the Composition API.

Lifecycle Hooks

Lifecycle hooks are also available with Vue 3’s composition API.

We put them all in the setup method.

For instance, we can write:

<template>
  <div></div>
</template>
@click
<script>
import { onMounted, onUnmounted, onUpdated } from "vue";
export default {
  name: "App",
  setup() {
    onMounted(() => {
      console.log("mounted!");
    });
    onUpdated(() => {
      console.log("updated!");
    });
    onUnmounted(() => {
      console.log("unmounted!");
    });
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

We pass in the callback into the lifecycle functions.

beforeCreate and created are replaced with the setup method.

And the following are the composition API equivalents of the options API hooks:

  • beforeMount -> onBeforeMount
  • mounted -> onMounted
  • beforeUpdate -> onBeforeUpdate
  • updated -> onUpdated
  • beforeDestroy -> onBeforeUnmount
  • destroyed -> onUnmounted
  • activated -> onActivated
  • deactivated -> onDeactivated
  • errorCaptured -> onErrorCaptured

The left side has the options API hooks and the right side has the composition API equivalents.

Composition API also have 2 debug hooks:

  • onRenderTracked
  • onRenderTriggered

We can write:

export default {
  onRenderTriggered(e) {
    debugger
  }
}
Enter fullscreen mode Exit fullscreen mode

to inspect which dependency is causing the component to re-render.

Dependency Injection

We can inject dependencies with the provide and inject functions.

provide and inject enables dependency injection similar to project and inject in Vue 2.x.

For instance, we can write:

<template>
  <div></div>
</template>
@click
<script>
import { provide, inject } from "vue";
@click
const ThemeSymbol = Symbol();
@click
const Ancestor = {
  setup() {
    provide(ThemeSymbol, "dark");
  },
};
@click
export default {
  name: "App",
  setup() {
    const theme = inject(ThemeSymbol, "light");
    return {
      theme,
    };
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

We have the Ancestor component, which calls provide to let us pass the dependency identified with ThemeSymbol down to the App component.

In App ‘s setup method, we call inject with ThemeSymbol to get the data passed in from provide .

'light' is the default value if nothing with the identifier ThemeSymbol is provided.

Template Refs

Composition API lets us access template refs.

We use the ref function to create the ref.

Then we can assign it in the template to the element or component we want.

For instance, we can write:

<template>
  <div ref="root"></div>
</template>
@click
<script>
import { ref, onMounted } from "vue";
@click
export default {
  name: "App",
  setup() {
    const root = ref(null);
@click
    onMounted(() => {
      console.log(root.value);
    });
@click
    return {
      root,
    };
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

We create the root ref with the ref function.

Then we set the name of the ref to the ref attribute.

Then root.value would be the div.

If we use a render function, we write:

<template>
  <div></div>
</template>
@click
<script>
import { ref, onMounted, h } from "vue";
@click
export default {
  name: "App",
  setup() {
    const root = ref(null);
@click
    onMounted(() => {
      console.log(root.value);
    });
@click
    return () =>
      h("div", {
        ref: root,
      });
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

to assign the ref to the div we create in the h function.

Conclusion

We can add lifecycle hooks and refs into our Vue 3 app with the composition API.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .