Reactivity Everywhere
Master the Composable Pattern
Juan Andrés Núñez
Frontend Engineer
@juanwmedia
Juan Andrés Núñez
Content creator at
@juanwmedia
Hot topic 🌶
What is a composable?
a "composable" is a function that leverages Vue Composition API to compose and reuse stateful logic.
☑️ Reusability
☑️ Stateful logic
☑️ Composition
Async scenario
<script setup>
import { ref } from "vue";
const API_URL = 'https://thecatapi.com/get'
const results = ref(null)
try {
const request = await fetch(API_URL)
const results.value = await request.json()
doSomeStuffWithTheResults(results)
} catch(err) {
throw new Error(err.message)
}
</script>
useAsync composable
import { ref, readonly } from "vue";
export function useAsync() {
const results = ref(null);
const error = ref(null);
const makeRequest = async (API_URL) => {
try {
const request = await fetch(API_URL);
const results = await request.json();
results.value = results;
} catch (err) {
error.value = err;
}
};
return {
makeRequest,
results: readonly(results),
error,
};
}
useAsync composable
import { ref, readonly } from "vue";
export function useAsync() {
const results = ref(null);
const error = ref(null);
const makeRequest = async (API_URL) => {
try {
const request = await fetch(API_URL);
const results = await request.json();
results.value = results;
} catch (err) {
error.value = err;
}
};
return {
makeRequest,
results: readonly(results),
error,
};
}
import { useAsync } from "./composables/useAsync";
const { result, error, makeRequest } = useAsync();
watchEffect(() => {
if (result.value) doSomeStuffWithTheResults(results.value);
if (error.value) throw new Error(error.value.message);
});
await makeRequest(API_URL);
Vue reactive API's outside components
import { ref, reactive } from "vue";
Let's write some composables 🔴
Stick to the basics
Scratch your own itch
Problem 1️⃣
Reuse logic
Tip 1️⃣
Start with the interface, not the implementation (IN / OUT).
✅ Reusability
☑️ Stateful logic
☑️ Composition
Problem 2️⃣
Maintaining state
useState pattern
import { reactive, readonly, toRefs } from 'vue';
// Like "data()" from Options API
let state = reactive({
isDark: false,
});
export function useState(newState = {}) {
const stateEntries = Object.entries(newState);
if (stateEntries.length)
for (const [key, value] of stateEntries) setState(key, value);
function setState(property, value) {
state[property] = value;
}
return {
state: toRefs(readonly(state)),
setState,
};
}
Tip 2️⃣
You can toggle between a stateful or stateless composable in the blink of an eye.
✅ Reusability
✅ Stateful logic
☑️ Composition
Problem 3️⃣
Persisting state
Tip 3️⃣
Compose composables
One composable can call another composable: creating small pieces of logic to mix and match as you like.
✅ Reusability
✅ Stateful logic
✅ Composition
Main takeaways
-
Now we can extract and reuse Vue's reactivity outside components for the first time.
- Every piece of code using reactivity now can be extracted and reused as a composable.
Final question 🥁
How much of your component's logic really belongs to the component?.
Recommendations
Don't go crazy
Don't try to reinvent the wheel:
Vue Use library
Thank you 🙏
Reactivity Vue 3
By Juan Andrés Núñez
Reactivity Vue 3
- 412