Vue Composition API reactivity out-of-the-box
Tags: javascript, vue, webdev, oop
Published: 2020-05-12 17:24:37

One of the features that Vue Core Team promises us from the upcoming Vue 3 is the reactivity out of the box and this is possible thanks to the freshly new Composition API proposed from [Evan You](https://www.youtube.com/watch?v=WLpLYhnGqPA). But you may be wondering how is this possible? I'll teach you a basic example on how you can use this feature using the OOP paradigm.

## Setting up the project

Firstly let's create a new basic project from the Vue CLI just to have a quick project in our hands:

```cmd
vue create basic-reactivity-project
```

And select the first option:

```cmd
default(babel, eslint)
```

Once the project is created let's install Vue Composition API plugin using:

```cmd
cd basic-reactivity-project
npm install --save @vue/composition-api
```

After the instalation, open your project in you text editor of your preference, in my case with VS Code.

Open up the `src/main.js` and add Composition API into your Vue project, your file should looks like this:

```js
import Vue from 'vue'
import CompApi from '@vue/composition-api' // <-- We need to import it just after Vue import
import App from './App.vue'

Vue.use(CompApi) // And use it like a normal plugin

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')
```

The setup is now ready!

## Building up a basic Class

Let's create a basic Class inside `src/classes` named Foo.js and inside the file make you to put this code:

```js
import { ref } from '@vue/composition-api' // We just need to add the ref Reactivity system from Composition API

class Foo {
  bar; //Normal property using a OOP approach

  constructor () {
    this.bar = ref('Foo') // Initialize the variable using the ref from Vue
  }

  // This getter function goes into our component and we need to pass the bar property inside an object to make this possible
  getter() {
    return {
      bar: this.bar
    }
  }

  // This method is only for example to see that the reactivity works
  handleForm() {
    console.log(
      this.bar
    )
  }
}

export default Foo

```

## Preparing the App.vue as a Composition API component

We need to make some few changes to make sure the component uses this new API, so let's change the code with this:

```html
<template>
  <div id="app">
    <input type="text" v-model="form.bar">
    <button @click="handleForm">Click me</button>
  </div>
</template>

<script>
// We need to call the ref once again to make sure the reactivity works in our component
import { defineComponent, ref, onMounted } from '@vue/composition-api'
import FooClass from './classes/FooClass'

export default defineComponent({
  name: 'App',
  setup () {
    // This const will receive the object from the class
    const form = ref({})

    // The class wrapper
    const service = new FooClass()

    // Just a handler
    const handleForm = () => {
      // Calling the handler from the class
      service.handleForm()
    }

    onMounted(() => {
      // Here is where the magic happends, we set the value into the form variable from the Foo class
      form.value = service.getter()
    })

    return {
      form,
      handleForm
    }
  }
});
</script>
```

And with this we have the project ready, and we need to run: `npm run serve`.

## Previewing the results

If we followed this guide, we should see in our browser the next image:

![The result from or build](https://i.imgur.com/rNLMTOa.png)

If we type in the input we can see the normal reactivity works as intended, but if you press in **Click me** we can see that this property works too inside the class, and will show us the actual value without passing the value in any function created from the class, the Reactivity works outside of Vue!!!!

![Reactivity outside of Vue component](https://i.imgur.com/qvj4Zrs.png)

Since I saw this possibility my mind melted, so I ask to you, are you interested in what is coming in Vue 3? Let's talk about it in the comment section.

You can check this project in this repo: <https://github.com/manuelojeda/vue-out-of-the-box>