Почему эти данные неправильно передаются от родительского компонента к дочернему компоненту в vue.js? - PullRequest
0 голосов
/ 06 июня 2019

У меня есть компонент vue, отвечающий за разбиение на страницы, так что на странице отображается только 20 элементов. Все работает, за исключением одного значения, которое мне нужно передать из родительского компонента, значения 'count', которое возвращает общее количество элементов.

Я использую значение 'count', чтобы вычислить, активна кнопка "Следующая страница" или нет, и каким должно быть общее количество страниц. Используя console.log, я вижу, что значение 'count' корректно возвращается в родительский компонент, но всегда возвращается как неопределенное в дочернем компоненте нумерации страниц. Посоветуйте, пожалуйста, как мне это исправить.

(Я не уверен, что использование часов здесь правильно; я думал, что это решит проблему, но это ничего не изменило.)

РЕДАКТИРОВАТЬ : я опубликовал больше как дочернего, так и родительского компонента для лучшего контекста.

Вот скрипт дочернего компонента:

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

Все элементы emit, серверный запрос и фактическая нумерация страниц работают нормально. Но кнопка «Моя следующая страница» неверна, и на кнопке «Последняя страница» отображается NaN, поскольку она не может выполнить правильные вычисления, когда count === undefined.

Заранее спасибо за помощь.

1 Ответ

1 голос
/ 06 июня 2019

Судя по вашим комментариям, вы на самом деле ничего не передаете в свой компонент.

Как подсказал @Dan, ваша count опора равна undefined, потому что от него ничего не передается от родителя. Чтобы передать свойство данных count от родительского объекта ребенку, необходимо использовать привязку шаблона <child v-bind:count="count"></child> или его сокращение <child :count="count"></child>.

Официальная документация является хорошей отправной точкой для понимания реквизита.

Вот минимальный пример.

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...