diff --git a/src/components/Navbar.vue b/src/components/Navbar.vue index 17f51d7..e78dbc7 100644 --- a/src/components/Navbar.vue +++ b/src/components/Navbar.vue @@ -18,6 +18,10 @@ Посты Vuex + + + Посты Composition + diff --git a/src/hooks/useCreateDialog.js b/src/hooks/useCreateDialog.js new file mode 100644 index 0000000..99fa05f --- /dev/null +++ b/src/hooks/useCreateDialog.js @@ -0,0 +1,22 @@ +import { ref, watch } from 'vue'; + +export default function useCreateDialog() { + const dialogVisible = ref(false); + + const showCreateDialog = () => { + dialogVisible.value = true; + } + + watch(dialogVisible, (newValue) => { + if (newValue) { + document.body.style.overflow = 'hidden'; + } else { + document.body.style.overflow = 'auto'; + } + }) + + return { + dialogVisible, + showCreateDialog + } +} diff --git a/src/hooks/usePosts.js b/src/hooks/usePosts.js new file mode 100644 index 0000000..5cd6d4b --- /dev/null +++ b/src/hooks/usePosts.js @@ -0,0 +1,55 @@ +import axios from 'axios'; +import { onMounted, ref } from 'vue'; + +export default function usePosts({page, limit}) { + const posts = ref([]); + const totalPages = ref(0); + const isPostLoading = ref(true); + + const fetchPosts = async () => { + try { + isPostLoading.value = true; + const { data, headers } = await axios.get(`https://jsonplaceholder.typicode.com/posts`, { + params: { + _limit: limit.value, + _page: page.value + } + }); + + posts.value = data; + totalPages.value = Math.ceil(headers['x-total-count'] / limit.value); + } catch (e) { + alert(e.message); + } finally { + isPostLoading.value = false; + } + } + + const loadMorePost = async () => { + page.value += 1; + + try { + const { data, headers } = await axios.get(`https://jsonplaceholder.typicode.com/posts`, { + params: { + _limit: limit.value, + _page: page.value, + } + }); + posts.value.push(...data); + totalPages.value = Math.ceil(headers['x-total-count'] / limit.value); + } catch (e) { + alert(e.message); + } + }; + + onMounted(fetchPosts); + + return { + posts, + totalPages, + isPostLoading, + fetchPosts, + loadMorePost, + page, + } +} diff --git a/src/hooks/useSortedAndSearchedPosts.js b/src/hooks/useSortedAndSearchedPosts.js new file mode 100644 index 0000000..cca83fb --- /dev/null +++ b/src/hooks/useSortedAndSearchedPosts.js @@ -0,0 +1,14 @@ +import { computed, ref } from 'vue'; + +export default function useSortedAndSearchedPosts (sortedPosts) { + const searchQuery = ref(''); + + const sortedAndSearchedPosts = computed(() => { + return sortedPosts.value.filter((post) => post.title.toLowerCase().includes(searchQuery.value.toLowerCase())) + }) + + return { + searchQuery, + sortedAndSearchedPosts + } +} diff --git a/src/hooks/useSortedPosts.js b/src/hooks/useSortedPosts.js new file mode 100644 index 0000000..1932986 --- /dev/null +++ b/src/hooks/useSortedPosts.js @@ -0,0 +1,16 @@ +import { computed, ref } from 'vue'; + +export default function useSortedPosts (posts) { + const selectedSort = ref(''); + + const sortedPosts = computed(() => { + return [...posts.value].sort((post1, post2) => { + return post1?.[selectedSort.value]?.localeCompare(post2?.[selectedSort.value]) + }) + }) + + return { + selectedSort, + sortedPosts + } +} diff --git a/src/pages/PostsPageWithCompositionApi.vue b/src/pages/PostsPageWithCompositionApi.vue new file mode 100644 index 0000000..152dd54 --- /dev/null +++ b/src/pages/PostsPageWithCompositionApi.vue @@ -0,0 +1,124 @@ + + + + + diff --git a/src/router/router.js b/src/router/router.js index 6c1d7a9..590cdce 100644 --- a/src/router/router.js +++ b/src/router/router.js @@ -4,6 +4,7 @@ import PostsPage from '@/pages/PostsPage.vue'; import AboutPage from '@/pages/AboutPage.vue'; import PostPage from '@/pages/PostPage.vue'; import PostsPageWithStore from '@/pages/PostsPageWithStore.vue'; +import PostsPageWithCompositionApi from '@/pages/PostsPageWithCompositionApi.vue'; const routes = [ { @@ -25,6 +26,10 @@ const routes = [ { path: '/store', component: PostsPageWithStore, + }, + { + path: '/composition', + component: PostsPageWithCompositionApi, } ]