Create Vue 3 Apps with the Composition API — Read-Only Properties and Side Effects
Tags: javascript, webdev, codenewbie, beginners
Published: 2021-01-17 23:10:48

**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/**


Vue 3 comes with the Composition API built-in.

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.

### Read-Only Property

We can add a read-only property to our Vue 3 app with the composition API.

To add it, we use the `readonly` property:

```
<template>
  <div>{{ copy }}</div>
</template>

<script>
import { reactive, readonly } from "vue";
export default {
  name: "App",
  setup() {
    const original = reactive({ count: 0 });
    const copy = readonly(original);
    return {
      copy,
    };
  },
};
</script>
```

We define the `original` reactive property with `reactive` .

Then we call `readonly` with `original` to create a read-only deep copy of the original.

And we return it, so we can use it.

### Watch Reactive Properties

We can watch reactive properties with the `watchEffect` method.

For instance, we can write:

```
<template>
  <div>{{ count }}</div>
</template>

<script>
import { ref, watchEffect } from "vue";
export default {
  name: "App",
  setup() {
    const count = ref(0);
    watchEffect(() => console.log(count.value));

    setTimeout(() => {
      count.value++;
    }, 100);

    return {
      count,
    };
  },
};
</script>
```

We call `watchEffect` with a callback to log the value of `count` when it’s updated in the `setTimeout` callback.

`watchEffect` returns a function that we can use to stop the watcher.

To use it, we write:

```
<template>
  <div>{{ count }}</div>
</template>

<script>
import { onBeforeUnmount, ref, watchEffect } from "vue";
export default {
  name: "App",
  setup() {
    const count = ref(0);
    const stop = watchEffect(() => console.log(count.value));

    setTimeout(() => {
      count.value++;
    }, 100);

    onBeforeUnmount(() => stop());

    return {
      count,
    };
  },
};
</script>
```

We call `stop` in the `onBeforeUnmount` callback to stop the watcher when we’re unmounting the component.

Also, we can invalidate side effects with the `onInvalidate` function.

For instance, we can write:

```
<template>
  <div>{{ size }}</div>
</template>

<script>
import { onBeforeMount, reactive, watchEffect } from "vue";
export default {
  name: "App",
  setup() {
    const size = reactive({
      width: 0,
      height: 0,
    });

    const onResize = () => {
      size.width = window.innerWidth;
      size.height = window.innerHeight;
    };
    onBeforeMount(() => window.addEventListener("resize", onResize));

    watchEffect((onInvalidate) => {
      onInvalidate(() => {
        window.removeEventListener("resize", onResize);
      });
    });

    return {
      size,
    };
  },
};
</script>
```

to call `window.removeEventListener` to remove the event listener in the `onInvalidate` callback.

The `onResize` function sets the `size` when we change the screen by attaching it as the listener for the `resize` event.

### Conclusion

We can add read-only properties and watch side effects with Vue 3’s composition API.