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

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

我有一个负责分页的vue组件,所以每页只显示20个项目。一切正常,除了我需要从父组件传递下来的一个值,即 returns 项目总数的 'count' 值。

我使用 'count' 值来计算 "Next Page" 按钮是否处于活动状态以及总页数应该是多少。使用 console.log 我可以看到 'count' 值 returns 正确地进入父组件,但它总是在子分页组件中返回为未定义。请告诉我如何解决这个问题。

(不知道这里用watch对不对,以为可以解决问题,结果什么都没变)

编辑:为了更好的上下文,我发布了更多的子组件和父组件。

子组件脚本如下:

<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>

这是来自父组件的(相关)脚本:

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()')
      })
    },

发射、服务器查询和实际分页元素都工作正常。但是我的下一页按钮是错误的,最后一页按钮显示 NaN 因为当 count === undefined.

时它无法 运行 正确计算

在此先感谢您的帮助。

从你的评论来看,你似乎并没有真正将任何东西传递给你的组件的 prop。

正如@Dan 所建议的那样,您的 count 道具是 undefined 因为没有从父级传递给它。要将 count 数据 属性 从父级传递给子级,您需要使用模板绑定 <child v-bind:count="count"></child> 或其 shorthand <child :count="count"></child>.

official documentation 是理解道具的一个很好的起点。

这是一个最小的例子。

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>