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

标签 javascript vue.js vue-component parent-child

我有一个负责分页的 vue 组件,因此每页仅显示 20 个项目。除了我需要从父组件传递下来的一个值(返回项目总数的“count”值)之外,一切都正常。

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

(我不确定这里使用 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 Prop 是 undefined因为没有任何东西从父级传递给它。通过count从父级到子级的数据属性需要使用模板绑定(bind) <child v-bind:count="count"></child>或其简写 <child :count="count"></child> .

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

这是一个最小的示例。

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>

关于javascript - 为什么在 vue.js 中这些数据无法正确地从父组件传递到子组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56481590/

相关文章:

javascript - 使用 javascript 验证 PHP 表单

javascript - 使用 vue 分布式文件中定义的函数

javascript - Vue.js .$set 不是函数

vue.js - 无法挂载组件 : template or render function not defined.(Vue 使用插件)

express - 职位发布不会删除,继续获取 id 是 "undefined"

javascript - 读取嵌入 JSON 的图表也会读取 JSON 文件吗?

javascript - 从尚未在 DOM 中的元素获取文本

javascript - 从选择框中显示确认删除框

vue.js - Vue-router beforeEach 在使用 next() 时陷入无限循环

javascript - Vuetify 文本区域为空或少于 200 个字符的规则