From 0eafaeb27f0ee88fa0dda7872973ec736489d2a3 Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Thu, 16 Jan 2025 06:40:25 +0300 Subject: [PATCH] add vuex --- src/components/Navbar.vue | 4 + src/main.js | 2 + src/pages/PostsPageWithStore.vue | 134 +++++++++++++++++++++++++++++++ src/router/router.js | 5 ++ src/store/index.js | 8 ++ src/store/postModule.js | 83 +++++++++++++++++++ 6 files changed, 236 insertions(+) create mode 100644 src/pages/PostsPageWithStore.vue create mode 100644 src/store/index.js create mode 100644 src/store/postModule.js diff --git a/src/components/Navbar.vue b/src/components/Navbar.vue index 515a17c..17f51d7 100644 --- a/src/components/Navbar.vue +++ b/src/components/Navbar.vue @@ -14,6 +14,10 @@ О Нас + + + Посты Vuex + diff --git a/src/main.js b/src/main.js index d386362..ed90e2a 100644 --- a/src/main.js +++ b/src/main.js @@ -4,6 +4,7 @@ import App from './App'; import components from '@/components/ui'; import dirictives from '@/dirictives'; import router from '@/router/router'; +import store from '@/store'; const app = createApp(App); @@ -18,4 +19,5 @@ dirictives.forEach(dirictive => { app .use(router) + .use(store) .mount('#app') diff --git a/src/pages/PostsPageWithStore.vue b/src/pages/PostsPageWithStore.vue new file mode 100644 index 0000000..0d8cc65 --- /dev/null +++ b/src/pages/PostsPageWithStore.vue @@ -0,0 +1,134 @@ + + + + + diff --git a/src/router/router.js b/src/router/router.js index 32fc3a8..6c1d7a9 100644 --- a/src/router/router.js +++ b/src/router/router.js @@ -3,6 +3,7 @@ import { createRouter, createWebHistory } from 'vue-router'; import PostsPage from '@/pages/PostsPage.vue'; import AboutPage from '@/pages/AboutPage.vue'; import PostPage from '@/pages/PostPage.vue'; +import PostsPageWithStore from '@/pages/PostsPageWithStore.vue'; const routes = [ { @@ -20,6 +21,10 @@ const routes = [ { path: '/about', component: AboutPage, + }, + { + path: '/store', + component: PostsPageWithStore, } ] diff --git a/src/store/index.js b/src/store/index.js new file mode 100644 index 0000000..7e9cf32 --- /dev/null +++ b/src/store/index.js @@ -0,0 +1,8 @@ +import { createStore } from 'vuex'; +import { postModule } from '@/store/postModule'; + +export default createStore({ + modules: { + post: postModule, + }, +}) diff --git a/src/store/postModule.js b/src/store/postModule.js new file mode 100644 index 0000000..2b8b337 --- /dev/null +++ b/src/store/postModule.js @@ -0,0 +1,83 @@ +import axios from 'axios'; + +export const postModule = { + state: () => ({ + posts: [], + isPostLoading: false, + selectedSort: '', + sortOptions: [ + {value: 'title', name: 'По названию'}, + {value: 'body', name: 'По описанию'} + ], + searchQuery: '', + page: 1, + limit: 10, + totalPages: 0 + }), + getters: { + sortedPost(state) { + return [...state.posts].sort((post1, post2) => { + return post1?.[state.selectedSort]?.localeCompare(post2?.[state.selectedSort]) + }) + }, + sortedAndSearchedPosts(state, getters) { + return getters.sortedPost.filter((post) => post.title.toLowerCase().includes(state.searchQuery.toLowerCase())) + } + }, + mutations: { + setPosts: (state, posts) => { + state.posts = posts + }, + setIsPostLoading: (state, isPostLoading) => { + state.isPostLoading = isPostLoading + }, + setSelectedSort: (state, selectedSort) => { + state.selectedSort = selectedSort + }, + setSearchQuery: (state, searchQuery) => { + state.searchQuery = searchQuery + }, + setPage: (state, page) => { + state.page = page + }, + setTotalPages: (state, totalPages) => { + state.totalPages = totalPages + }, + }, + actions: { + async fetchPosts({state, commit}) { + try { + commit('setIsPostLoading', true); + const { data, headers } = await axios.get(`https://jsonplaceholder.typicode.com/posts`, { + params: { + _limit: state.limit, + _page: state.page + } + }); + + commit('setPosts', data); + commit('setTotalPages', Math.ceil(headers['x-total-count'] / state.limit)) + } catch (e) { + alert(e.message); + } finally { + commit('setIsPostLoading', false); + } + }, + async loadMorePost({state, commit}) { + commit('setPage', state.page + 1) + try { + const { data, headers } = await axios.get(`https://jsonplaceholder.typicode.com/posts`, { + params: { + _limit: state.limit, + _page: state.page, + } + }); + commit('setPosts', [...state.posts, ...data]); + commit('setTotalPages', Math.ceil(headers['x-total-count'] / state.limit)) + } catch (e) { + alert(e.message); + } + }, + }, + namespaced: true, +}