IvanInvanov
@IvanInvanov
Новичок

Как передать пост из одного компонента в другой?

Добрый день, подскажите пожалуйста. Я сейчас тренируюсь с использованием Vuex и у меня не получается передать пост из одного компонента в другой. У меня есть компонент Pagination, где хранятся все посты и компонент history куда и должны отправлять первые 5 постов на которые я нажимаю чтобы посетить их. То есть должно работать примерно как история просмотров постов. Я написал здесь некоторый код, но посты у меня не отображаются, подскажите пожаkeйста что я не правильно делаю и как это исправить.

Код компонента где хранятся все посты:

<template>
  <div class = "app">
    <ul>
      <li v-for="(post, index) in paginatedData" class="post" :key="index">
        <router-link :to="{ name: 'detail', params: {id: post.id, title: post.title, body: post.body} }" @click="addPostToHistoryComp(post.id, post.title, post.body)">
        <img src="src/assets/nature.jpg">
        <p class="boldText"> {{ post.title }}</p>
        </router-link>
        <p> {{ post.body }}</p>
      </li>
      </ul>
      </div>
    </template>

    <script>
      import {mapState} from 'vuex'
      export default {
        name: 'app',
        mounted(){
          this.$store.dispatch('loadPosts')
        },
        computed: {
          posts(){
            return this.$store.state.posts
          },
          search(){
            return this.$store.state.sSearch
          },
          evenPosts: function(posts){
            return Math.ceil(this.posts.length/6);
          },
          paginatedData() {
            const start = this.page * 6;
            const end = start + 6;
            return this.filteredPosts.slice(start, end);
          },
          filteredPosts() {
            return this.posts.filter((post) => {
              return post.title.match(this.search);
            });
          },
        },
        methods: {
          addPostToHistoryComp(val){
            this.$store.dispatch('transforPostToHistoryComp', { 
              pTitle: val.post.title,
              pBody: val.post.body,
              pId: val.post.id
            })
          },
        }
      }
    </script>


Код компонента History где должны отображаться последние 5 постов которые открывал:
<template>
  <div class="history">
    <ul>
      <li v-for="(historyPost, index) in historyPosts" class="post" :key="index">        
        <img src="src/assets/nature.jpg">
        <p class="boldText"> {{ post.title }}</p>
        <p> {{ post.body }}</p>
      </li>
      </ul>
  </div>
</template>

<script>
  export default{
    computed: {
      historyPosts(){
        return this.$store.state.historyPosts
      },
    },

  }
</script>


И код моего стора(Vuex):
export default new vuex.Store({
  state: {
    posts: [],
    sSearch: '',
    title: '',
    body: '',
    id: Number,
    historyPosts: []
  },
  actions: {
    loadPosts ({commit}) {
      axios.get('http://jsonplaceholder.typicode.com/posts').then(response => {
        let posts = response.data
        commit('SET_POSTS', posts)
      }).catch(error => {
        console.log(error);
      })
    },
    transforTitleAndBody({commit}, payload){ 
      const todo = {
        title: payload.sTitle,
        body: payload.sBody,
        id: payload.sId
      }
      axios.post('http://jsonplaceholder.typicode.com/posts', todo).then(_ => {
        commit('ADD_TODO', todo)
      }).catch(function (error) {
          console.log(error);
        })
    },
    transforPostToHistoryComp({commit}, payload){ 
      const todohistory = {
        title: payload.pTitle,
        body: payload.pBody,
        id: payload.pId
      }
      commit('ADD_TODO_HISTORY', todo)
    }
  },
  mutations: {
    SET_POSTS(state, posts) {
      state.posts = posts
    },
    transforSearch(state, payload){ 
      state.sSearch = payload
    },
    ADD_TODO (state, todoObject) {
      state.posts.unshift(todoObject)
    },
    ADD_TODO_HISTORY (state, todohistoryObject) {
      state.historyPosts.unshift(todoObject)
    },
  },
})
  • Вопрос задан
  • 201 просмотр
Решения вопроса 1
0xD34F
@0xD34F Куратор тега Vue.js
Код компонента где хранятся все посты:

Неправда, посты вы храните не здесь, вы же vuex используете.

@click="addPostToHistoryComp(post.id, post.title, post.body)"

А если вы не через эту ссылку пост откроете? Добавление в историю должно выполняться из компонента поста. Да и не сработает этот обработчик клика - router-link событие клика не генерирует (можно подписаться на click.native).

paginatedData() {
  const start = this.page * 6;

Что такое page? - не вижу в компоненте свойства с таким именем. В результате у вас start и end оказываются NaN, а массив постов текущей страницы, соответственно, пустой.

addPostToHistoryComp(val){
  this.$store.dispatch('transforPostToHistoryComp', { 
    pTitle: val.post.title,

Что ещё за val.post? - вы же передаёте в метод отдельно id, title и body. Лучше передавайте объект поста целиком.

<li v-for="(historyPost, index) in historyPosts" class="post" :key="index">        
  <img src="src/assets/nature.jpg">
  <p class="boldText"> {{ post.title }}</p>

Так как всё-таки правильно будет - historyPost или просто post?

const todohistory = {
  title: payload.pTitle,
  body: payload.pBody,
  id: payload.pId
}
commit('ADD_TODO_HISTORY', todo)

Объявляете todohistory, а в мутацию передаёте какой-то непонятный todo. Это как?

ADD_TODO_HISTORY (state, todohistoryObject) {
  state.historyPosts.unshift(todoObject)
},

Тоже непонятно: todoObject - что это, кто это, зачем это, откуда он взялся?

UPD. Вот вам ваш код, приведённый в относительно рабочее состояние, думайте.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы