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 @@
+
+
+
Страница постов (Composition API)
+
+
+
+
+
+ Создать пост
+
+
+
+
+
+
+
+
+
+
Loading...
+
+
+
+
+
+
+
+
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,
}
]