Vue.js, composition API, "Mixins" and life-cycle hooks

Viewed 5868

I've been looking all around (and I couldn't find) an answer for the following.

In Vue 2.x, you could use mixins for life-cycle hooks, i.e., for instance: I could create a Mixins.js with

export default {
  created() {
    console.log('test');
  }
}

and then, in a component, do the following:

import mixins from "../misc/mixins";

export default {
  name: "My component",
  mixins: [mixins],
  created() {
    console.log('Another test');
  }
}

And if I ran "My component", I would get in the console both "Another test" and "test". I cannot find the way of doing something similar with the Composition API (of course, I can execute inside "onMounted" a functions that I imported from another file, but that's not that elegant).

Is there a way?

Thanks!

1 Answers

With Composition API you have to import lifecycles you need. Docs with list: https://v3.vuejs.org/guide/composition-api-lifecycle-hooks.html

Component.vue

<script>
import { onMounted } from 'vue'

export default {
  setup(props) {
    console.log('CREATED')
    onMounted(() => {
      console.log('MOUNTED')
    });

    return {};
  },
}
</script>

Note that there is no onCreated(). From docs:

Because setup is run around the beforeCreate and created lifecycle hooks, you do not need to explicitly define them. In other words, any code that would be written inside those hooks should be written directly in the setup function.

But what about using this as Mixins alternative?

Now if you want you can simply extract this to separate file, often called composable.

demoLifehooks.js

import { onMounted } from 'vue'

export default () => {
  console.log('Created')
  onMounted(() => {
    console.log('Mounted')
  })
}

Now simply import it and execute.

Component.vue

<script>
import useDemoLifecycles from './demoLifecycles.js'

export default {
  setup(props) {
    useDemoLifecycles()

    return {};
  },
}
</script>

or even shorter thanks to new script setup syntax.

<script setup>
import useDemoLifecycles from './demoLifecycles.js'
useDemoLifecycles()
</script>

Log in console:

Created
Mounted

Live example

Naming it as useSomething is just convention. It will be not a bad idea to force it by exporting not default function but named one:

export const useDemoLifecycles = () => { console.log('code here') }

and then

import { useDemoLifecycles } from './demoLifecycles'

Also, if you want refs or other data from that file, it will be

const { a, b } = useDemoLifecycles() 

Notice that actually in my examples there is not much Vue's "magic", like it was with Mixins. This is pretty much pure JS stuff and not Vue specific code. So it is actually simpler than old Options API + Mixins.

Related