简体   繁体   中英

Problems with data communication between components

I had a page on which there was a header with an input that was a search engine, a list of posts, and pagination. I decided to move the header from this file to a separate component in a separate vue file. After I did this, the search for posts by title stopped working, and I can't add a post now either. I think that I need to import my posts into a new file for my newly created component but how to do it.

My code when it worked(before my changes)

My code is not working after the changes:

The file in which my posts situated:

<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} }">
          <img src="src/assets/nature.jpg">
          <p class="boldText"> {{ post.title }}</p>
        </router-link>
        <p> {{ post.body }}</p>

    </li>

  </ul>
  <div class="allpagination">
    <button type="button" @click="page -=1" v-if="page > 0" class="prev"><<</button>
    <div class="pagin">
      <button class="item"
      v-for="n in evenPosts"
      :key="n.id"
      v-bind:class="{'selected': current === n.id}"
      @click="page=n-1">{{ n }} </button>
    </div>
    <button type="button" @click="page +=1" class="next" v-if="page < evenPosts-1">>></button>
  </div>

</div>
</template>

<script>
  import axios from 'axios';
  export default {
    name: 'Pagination',
    data () {
      return {
        search: '',
        current: null,
        page: 0,
        posts: [],
        createTitle: '',
        createBody: '',
        visiblePostID: '',
      }
    },
    watch: {
      counter: function(newValue, oldValue) {
        this.getData()
      }
    },
    created(){
      this.getData()
    },
    computed: {
      evenPosts: function(posts){
        return Math.ceil(this.posts.length/6);
      },

      paginatedData() {
        const start = this.page * 6;
        const end = start + 6;
        return this.posts.filter((post) => {
          return post.title.match(this.search);
        }).slice(start, end);
      },
    },
    methods: {
      getData() {
        axios.get(`https://jsonplaceholder.typicode.com/posts`).then(response => {
          this.posts = response.data
        })
      },

    }
  }
</script>

Header vue:

AddPost

<template>
  <div id="app">
    <header-self></header-self>
    <router-view></router-view>
  </div>
</template>

<script>

export default {
  components: {
    name: 'app',
  }
}
</script>

App.vue:

 <template> <div id="app"> <header-self></header-self> <router-view></router-view> </div> </template> <script> export default { components: { name: 'app', } } </script>

You have a computed property paginatedData in your "posts" component that relies a variable this.search :

paginatedData () {
  const start = this.page * 6;
  const end = start + 6;
  return this.posts.filter((post) => {
    return post.title.match(this.search);
  }).slice(start, end);
},

but this.search value is not updated in that component because you moved the search input that populates that value into the header component.

What you need to do now is make sure that the updated search value is passed into your "posts" component so that the paginatedData computed property detects the change and computes the new paginatedData value.

You're now encountering the need to pass values between components that may not have a parent/child relationship.

In your scenario, I would look at handling this need with some Simple State Management as described in the Vue docs.

Depending on the scale of you app it may be worth implementing Vuex for state management.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM