I have a vue component responsible for pagination, so that only 20 items are shown per page. 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. 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.)
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
.
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. 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>
.
The official documentation is a good starting point for understanding 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>
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.