简体   繁体   English

为什么在 vue.js 中这些数据不能正确地从父组件传递到子组件?

[英]Why is this data not correctly passing from parent component to child component, in vue.js?

I have a vue component responsible for pagination, so that only 20 items are shown per page.我有一个负责分页的 vue 组件,所以每页只显示 20 个项目。 Everything is working except for the one value that I need passed down from the parent component, the 'count' value that returns the total number of items.一切正常,除了我需要从父组件传递的一个值,即返回项目总数的“计数”值。

I use the 'count' value to calculate whether the "Next Page" button is active or not and what the total number of pages should be.我使用“计数”值来计算“下一页”按钮是否处于活动状态以及总页数应该是多少。 Using console.log I can see that the 'count' value returns correctly in to the parent component, but it always comes back as undefined in the child pagination component.使用 console.log 我可以看到“计数”值正确返回到父组件,但它总是在子分页组件中返回为未定义。 Please advise how I can fix this.请告诉我如何解决这个问题。

(I'm not sure if using watch here is correct; I thought it would solve the problem, but it changed nothing.) (我不确定在这里使用 watch 是否正确;我认为它会解决问题,但它没有改变。)

EDIT : I've posted more of both the child and parent component for better context.编辑:为了更好的上下文,我发布了更多的子组件和父组件。

Here is the script of the child component:这是子组件的脚本:

<script>
  export default {
    name: 'Pagination',
    props: ['count'],
    watch: {
      count: function (val, oldVal) {}
    },
    data () {
      return {
        currentPage: 1,
        limit: 20,
        paginationVisible: true,
        firstPageIsCurrent: true,
        prevEllipsisVisible: false,
        pageLink1: 2,
        pageLink1Visible: true,
        pageLink1IsCurrent: false,
        pageLink2: 3,
        pageLink2Visible: true,
        pageLink2IsCurrent: false,
        pageLink3: 4,
        pageLink3Visible: true,
        pageLink3IsCurrent: false,
        nextEllipsisVisible: true,
        lastPageVisible: true,
        lastPageIsCurrent: false,
        prevDisabled: true,
        nextDisabled: false,
        lastPage: 1
      }
    },
    methods: {
      handlePrev () {
        if (!this.prevDisabled) {
          this.currentPage -= 1
          this.paginate()
        }
      },
      handleNext () {
        if ((this.currentPage * this.limit) < this.count) {
          this.currentPage += 1
          this.paginate()
        }
      },
      handleFirstPage () {
        if (this.currentPage !== 1) {
          this.currentPage = 1
          this.paginate()
        }
      },
      handlePageLink1 () {
        if (this.currentPage !== this.pageLink1) {
          this.currentPage = this.pageLink1
          this.paginate()
        }
      },
      handlePageLink2 () {
        if (this.currentPage !== this.pageLink2) {
          this.currentPage = this.pageLink2
          this.paginate()
        }
      },
      handlePageLink3 () {
        if (this.currentPage !== this.pageLink3) {
          this.currentPage = this.pageLink3
          this.paginate()
        }
      },
      handleLastPage () {
        if (this.currentPage < this.lastPage) {
          this.currentPage = this.lastPage
          this.paginate()
        }
      },
      paginateAdjust () {
        console.log(this.count)
        // adjust pagination bar and previous/next buttons
        this.nextDisabled = ((this.currentPage * this.limit) >= this.count)
        this.prevDisabled = (this.currentPage === 1)
        const pageCount = Math.ceil(this.count / this.limit)
        // console.log(pageCount + ', cp: ' + this.currentPage)
        if (pageCount === 1) {
          this.paginationVisible = false
        } else {
          this.paginationVisible = true
          // first page link
          this.firstPageIsCurrent = this.currentPage === 1
          // previous ellipsis
          this.prevEllipsisVisible = this.currentPage > 3 && pageCount > 5
          // first page link
          this.pageLink2Visible = pageCount > 2
          if (this.currentPage < 4) {
            this.pageLink1 = 2
          } else if ((pageCount - this.currentPage) < 3) {
            this.pageLink1 = pageCount - 3
          } else {
            this.pageLink1 = this.currentPage - 1
          }
          this.pageLink1IsCurrent = this.pageLink1 === this.currentPage
          // second page link
          this.pageLink2Visible = pageCount > 3
          if (this.currentPage < 4) {
            this.pageLink2 = 3
           } else if ((pageCount - this.currentPage) < 3) {
            this.pageLink2 = pageCount - 2
          } else {
            this.pageLink2 = this.currentPage
          }
           this.pageLink2IsCurrent = this.pageLink2 === this.currentPage
          // third page link
          this.pageLink3Visible = pageCount > 4
          if (this.currentPage < 4) {
            this.pageLink3 = 4
          } else if ((pageCount - this.currentPage) < 3) {
            this.pageLink3 = pageCount - 1
          } else {
            this.pageLink3 = this.currentPage + 1
          }
          this.pageLink3IsCurrent = this.pageLink3 === this.currentPage
          // next ellipsis
          this.nextEllipsisVisible = ((pageCount - this.currentPage) >= 3) && pageCount > 5
          // last page
          this.lastPage = pageCount
          this.lastPageIsCurrent = this.currentPage === pageCount
        }
      },
      emitMSQ () {
        this.$emit('msq', this.currentPage, this.limit)
      },
      paginate () {
        this.paginateAdjust()
        this.emitMSQ()
      }
    },
    created () {
      this.paginate()
    }
  }
</script>

Here is the (relevant) script from the parent component:这是来自父组件的(相关)脚本:

export default {
  name: 'index',
  components: {Pagination},
  computed: {
    apps () {
      return this.$store.state.apps
    }
  },
  data () {
    return {
      apps: [],
      count: 0,
      searchAddress: ''
    }
  },
  methods: {
    onSearch () {
      if (this.searchAddress.length === 12 || this.searchAddress.length === 0) {
        this.currentPage = 1
        this.makeServerQuery()
      }
    },
    makeServerQuery (cp, pp) {
      let queryStr = '?uid=' + this.$auth.user().id + '&cp=' + cp + '&pp=' + pp
      if (this.searchAddress.length === 12) {
        queryStr += '&se=' + this.searchAddress
      }
      this.$http.get('/apps' + queryStr).then(res => {
        this.apps = res.data.apps
        this.count = res.data.count
        console.log(this.count + ' msq()')
      })
    },

The emit, server query, and actual pagination elements all work fine.发射、服务器查询和实际分页元素都可以正常工作。 But my next page button is wrong and the last page button displays NaN because it can't run the correct calculations when count === undefined .但是我的下一页按钮是错误的,最后一页按钮显示NaN因为它在count === undefined时无法运行正确的计算。

Thanks in advance for the help.在此先感谢您的帮助。

From your comments, it looks like you are not really passing anything to your component's prop.从您的评论来看,您似乎并没有真正将任何东西传递给组件的道具。

As @Dan suggested, your count prop is undefined because nothing is being passed to it from the parent.正如@Dan 所建议的那样,您的count道具是undefined的,因为没有从父级传递给它。 To pass the count data property from the parent to the child you need to use a template binding <child v-bind:count="count"></child> or its shorthand <child :count="count"></child> .要将count数据属性从父级传递给子级,您需要使用模板绑定<child v-bind:count="count"></child>或其简写<child :count="count"></child>

The official documentation is a good starting point for understanding props. 官方文档是理解 props 的一个很好的起点。

Here's a minimal example.这是一个最小的例子。

 Vue.config.productionTip = false; Vue.component('child', { template: ` <div class="child"> from parent: {{count}} <br> <button :disabled="!enableNext" @click="onNext">Next</button> </div> `, props: ['count'], computed: { enableNext() { return this.count && this.count > 0; } }, methods: { onNext() { console.log('Go to page ' + this.count + 1) } } }) new Vue({ el: '#app', template: ` <div class="parent"> Parent count: {{ count }} <child :count="count" /> <br> <button @click="count++">Increment count</button> </div> `, data:() => ({ count: 0 }) });
 div { border: solid 1px black; padding: 1em; } .child { background: lightgray; } button:disabled, button[disabled]{ border: 1px solid #999999; background-color: #cccccc; color: #666666; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"></div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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