When working with Vue 3 Composition API and Pinia, I struggled a bit to put out an example of loading async data, where the request is handled by the Pinia store, which also owns the data.
It’s 2 AM and, finally, here is the store:
import {ref, reactive} from 'vue';
import {defineStore} from 'pinia';
const useStore = defineStore('fruits', () => {
const fruits = reactive<string[]>([]);
const loading = ref(false);
return {
fruits,
loading,
loadFruits(): Promise<void> {
loading.value = true;
return new Promise((resolve, _reject) => {
setTimeout(() => {
fruits.push('lemon', 'orange', 'peach', 'strawberry');
loading.value = false;
resolve();
}, 2000);
});
},
};
});
export default useStore;
And this is the single file component, which calls the store asynchronously:
<template>
<div v-if="loading">Loading...<div>
<div v-if="!loading">
<div v-for="fruit of fruits" :key="fruit">
{{fruit}}
</div>
</div>
</template>
<script setup lang="ts">
import {computed, onMounted} from 'vue';
import useStore from '@/model/store';
const store = useStore();
const loading = computed(() => store.loading);
const fruits = computed(() => store.fruits);
onMounted(() => {
store.loadFruits();
});
</script>
Although I’m not seeing much advantage of Vue over React, Pinia is so much better than Redux insanity. Even with Redux Toolkit. I hope they don’t mess it up when Pinia becomes Vuex 5, as said.