135 lines
3.0 KiB
Vue
135 lines
3.0 KiB
Vue
<template>
|
|
<div>
|
|
<h1>Страница постов (Vuex)</h1>
|
|
|
|
<my-input
|
|
v-focus
|
|
:model-value="searchQuery"
|
|
@update:model-value="setSearchQuery"
|
|
placeholder="Поиск"
|
|
class="search"
|
|
/>
|
|
|
|
<div class="app__btns">
|
|
<my-button @click="showCreateDialog" class="createBtn">
|
|
Создать пост
|
|
</my-button>
|
|
|
|
<my-select
|
|
:model-value="selectedSort"
|
|
@update:model-value="setSelectedSort"
|
|
:options="sortOptions"
|
|
/>
|
|
</div>
|
|
|
|
<my-dialog v-model:show="dialogVisible">
|
|
<post-form @createPost="createPost" />
|
|
</my-dialog>
|
|
|
|
<div v-if="isPostLoading" style="margin-top: 15px">Loading...</div>
|
|
|
|
<post-list v-else :posts="sortedAndSearchedPosts" @removePost="removePost" class="postList"/>
|
|
|
|
<div v-intersection="getIntersectionData()" ref="observer" class="observer"></div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import PostForm from '@/components/PostForm.vue';
|
|
import PostList from '@/components/PostList.vue';
|
|
import {mapActions, mapState, mapGetters, mapMutations} from 'vuex';
|
|
|
|
export default {
|
|
components: {
|
|
PostForm,
|
|
PostList
|
|
},
|
|
data() {
|
|
return {
|
|
dialogVisible: false,
|
|
}
|
|
},
|
|
methods: {
|
|
...mapMutations({
|
|
setPage: 'post/setPage',
|
|
setSearchQuery: 'post/setSearchQuery',
|
|
setSelectedSort: 'post/setSelectedSort',
|
|
}),
|
|
...mapActions({
|
|
fetchPosts: 'post/fetchPosts',
|
|
loadMorePost: 'post/loadMorePost'
|
|
}),
|
|
createPost(newPost) {
|
|
this.posts.push(newPost);
|
|
this.dialogVisible = false;
|
|
},
|
|
removePost(post) {
|
|
this.posts = this.posts.filter(p => p.id !== post.id)
|
|
},
|
|
showCreateDialog() {
|
|
this.dialogVisible = true;
|
|
},
|
|
getIntersectionData() {
|
|
return {
|
|
loadMorePost: this.loadMorePost,
|
|
page: this.page,
|
|
totalPages: this.totalPages,
|
|
}
|
|
}
|
|
},
|
|
computed: {
|
|
...mapState({
|
|
posts: (state) => state.post.posts,
|
|
isPostLoading: (state) => state.post.isPostLoading,
|
|
selectedSort: (state) => state.post.selectedSort,
|
|
sortOptions: (state) => state.post.sortOptions,
|
|
searchQuery: (state) => state.post.searchQuery,
|
|
page: (state) => state.post.page,
|
|
limit: (state) => state.post.limit,
|
|
totalPages: (state) => state.post.totalPagess
|
|
}),
|
|
...mapGetters({
|
|
sortedPost: 'post/sortedPost',
|
|
sortedAndSearchedPosts: 'post/sortedAndSearchedPosts'
|
|
})
|
|
},
|
|
watch: {
|
|
dialogVisible(newValue) {
|
|
if (newValue) {
|
|
document.body.style.overflow = 'hidden';
|
|
} else {
|
|
document.body.style.overflow = 'auto';
|
|
}
|
|
},
|
|
},
|
|
mounted() {
|
|
this.fetchPosts();
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
.createBtn {
|
|
margin-top: 15px;
|
|
}
|
|
|
|
.postList {
|
|
margin-top: 15px;
|
|
}
|
|
|
|
.app__btns {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.search {
|
|
margin-top: 15px;
|
|
}
|
|
|
|
.observer {
|
|
height: 0px;
|
|
background: teal;
|
|
}
|
|
</style>
|