Global reactive store based on Composition API refs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// src/services/books.ts | |
// $fetch is a custom fetch wrapper performing common operations, we plan to release it as open source when we'll have time | |
// Should be easy to understand what it does | |
type Book = { | |
id: number; | |
title: string; | |
isbn: string; | |
price: number; | |
}; | |
type BookData = { | |
title: string; | |
isbn: string; | |
price: number; | |
}; | |
// We cannot assign it here because VueCompositionAPI isn't initialized yet | |
// But we need the common "store" for all instances | |
// With Vue3 it will be possible to assign it outside too | |
let books!: Ref<Book[]>; | |
export function useBookService() { | |
// We initialize the singleton the first time we call the composable | |
!books && (books = ref([])); | |
const getAll = () => | |
$fetch('/books', { | |
method: 'GET', | |
onSuccess: (jsonData) => (books.value = jsonData), | |
}); | |
const create = (bookData: BookData) => | |
$fetch('/books', { | |
method: 'POST', | |
data: bookData, | |
}); | |
const destroy = (bookId: number) => | |
$fetch(`/books/${bookId}`, { | |
method: 'DELETE', | |
onSuccess: () => { | |
const deletedBookIndex = findIndex(books.value, ['id', bookId]); | |
deletedBookIndex !== -1 && books.value.splice(deletedBookIndex, 1); | |
}, | |
}); | |
return { | |
books, | |
getAll, | |
create, | |
destroy, | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// src/pages/bookshelf.vue | |
<script> | |
import { defineComponent } from "@vue/composition-api"; | |
import { useBookService } from "src/services/books"; | |
export default defineComponent({ | |
name: 'PageBookshelf', | |
setup() { | |
const { books, getAll: getBooks } = useBookService(); | |
onMounted(getBooks); | |
return { books }; | |
} | |
}); | |
</script> | |
<template> | |
<div> | |
<q-list> | |
<q-item v-for="book in books" :key="book.id">{{ book.title }}</q-item> | |
</q-list> | |
</div> | |
</template> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment