Creating Vue 3 Applications with the Composition API: Custom Refs
Written on
Chapter 1: Introduction to Vue 3's Composition API
The Composition API in Vue 3 simplifies the extraction of logic from components, eliminating concerns about the this context in your code. This feature enhances compatibility with TypeScript, as it removes the need for typing the this context. In this article, we will delve into the process of developing Vue 3 applications utilizing the Composition API.
Section 1.1: Creating Custom Refs
To create a custom ref, we can use the customRef function. Below is an example implementation:
caption: | Custom Ref Example |
---|
<template>
<div>
<input v-model="text" />
{{ text }}
</div>
</template>
<script>
import { customRef } from "vue";
const useDebouncedRef = (value, delay = 200) => {
let timeout;
return customRef((track, trigger) => {
return {
get() {
track();
return value;
},
set(newValue) {
clearTimeout(timeout);
timeout = setTimeout(() => {
value = newValue;
trigger();
}, delay);
},
};
});
};
export default {
name: "App",
setup() {
return {
text: useDebouncedRef("hello world"),};
},
};
</script>
In this example, we define the useDebouncedRef function, which returns a custom ref created using the customRef function. The function includes a callback that utilizes the track method to observe the value, and the setter invokes trigger to update the state.
Section 1.2: Utilizing markRaw
The markRaw function allows us to designate an object so that it remains unaltered by Vue's reactivity system. Here's how it works:
caption: | markRaw Example |
---|
<template>
<div></div></template>
<script>
import { isReactive, markRaw, reactive } from "vue";
export default {
name: "App",
setup() {
const foo = markRaw({});
console.log(isReactive(reactive(foo)));
return { foo };
},
};
</script>
In this snippet, the console log outputs false since markRaw prevents the object from being reactive. If we reference this raw object in another reactive structure, they will not be considered equal despite sharing the same reference.
Chapter 2: Understanding Shallow Reactivity
In this video, you will learn about the Vue 3 Composition API, specifically focusing on custom refs, reactive properties, and how to manage state effectively.
Section 2.1: Creating Shallow Reactive Objects
We can also generate a shallow reactive object using the shallowReactive function. This limits reactivity to the top-level properties of the object. Here’s a demonstration:
caption: | Shallow Reactive Example |
---|
<template>
<div>
<button @click="increment">increment</button>
{{ state.foo }}
{{ state.nested.bar }}
</div>
</template>
<script>
import { isReactive, shallowReactive } from "vue";
export default {
name: "App",
setup() {
const state = shallowReactive({
foo: 1,
nested: {
bar: 2,},
});
const increment = () => {
state.foo++;
state.nested.bar++;
};
console.log(isReactive(state.nested.bar));
return { state, increment };},
};
</script>
When the increment function is called, both state.foo and state.nested.bar are updated in the template. However, logging isReactive(state.nested.bar) results in false, indicating it is not reactive.
This tutorial explains the differences between ref and reactive in Vue 3, focusing on how to use the Composition API effectively.
Section 2.2: Watchers and Shallow Reactivity
When using watchers with shallow reactive objects, the callbacks may not execute as expected:
caption: | Watchers with Shallow Reactive |
---|
<template>
<div>
<button @click="increment">increment</button>
{{ state.foo }}
{{ state.nested.bar }}
</div>
</template>
<script>
import { isReactive, shallowReactive, watch } from "vue";
export default {
name: "App",
setup() {
const state = shallowReactive({
foo: 1,
nested: {
bar: 2,},
});
const increment = () => {
state.foo++;
state.nested.bar++;
};
watch(state.nested.bar, (bar) => {
console.log(bar);});
return { state, increment };
},};
</script>
In this example, the watcher on state.nested.bar will not trigger the callback upon updates since it is not reactive.
Conclusion
Vue 3’s Composition API provides a versatile set of functions for creating reactive and non-reactive properties, allowing developers to build more efficient applications.