<template>
<!-- 因为 Vue 要求每个组件只能有一个 root 元素,故这里需要使用 `div` 将 `a` 标签包裹起来 -->
<div>
<a href="javascript:void(0);"
v-for="num in totalPage"
:class="{active: currentPage === num}"
@click="changePage(num)"
>第{{num}}页</a>
</div>
</template>
<script>
module.exports = {
data() {
return {
};
},
// 重新映射 `v-model` 的属性值
model: {
prop: 'currentPage', // 默认为 `value`,
event: 'changeCurrentPage', // 默认为 `input`
},
// `props` 属性:用于向子组件传递数据
// 注意命名自动转换规则
props: ['totals', 'pageSize', 'currentPage'],
computed: {
totalPage() {
// 每页 `pageSize` 条,有小数,则+1
// 若列表长度为0,则显示1
return Math.ceil(this.totals / this.pageSize) || 1;
}
},
methods: {
changePage(num) {
// 触发 `v-model` 事件
this.$emit('changeCurrentPage', num);
}
}
};
</script>
<style scoped></style>
<template>
<dl>
<dt>图书列表(单文件组件)</dt>
<dd class="page">
<!-- Vue.js 为 components 和 props 提供了自动命名大小写转换规则,
但并没有为自定义事件提供此类自动命名转换规则,
详见:https://vuejs.org/v2/guide/components-custom-events.html#Event-Names -->
<page-bar
:totals="bookTotal"
:page-size="pageSize"
v-model="currentPage"></page-bar>
</dd>
<dd>
<input type="text" v-model="currentPage">
<!-- 等同于 -->
<input type="text" :value="currentPage" @input="currentPage = $event.target.value">
</dd>
<dd v-for="book in bookList">
{{book.row_index}}. 《{{book.book_name}}》 - CN¥{{book.book_price}} - {{book.book_press}}
</dd>
</dl>
</template>
<script>
const PageBar = httpVueLoader('../common/PageBar.vue');
// 注意:这里必须是以 CommonJS(Node.js) 的 `module.exports` 方式导出,而不能是 ES6 的 `export default`
// 建议阅读:https://stackoverflow.com/questions/40294870/module-exports-vs-export-default-in-node-js-and-es6
module.exports = {
// 组件中的 `data` 必须为函数
data() {
return {
bookList: [],
bookTotal: 0,
pageSize: 10,
currentPage: 1
};
},
created() {
this.getBookList();
},
beforeUpdate() {
this.getBookList();
},
methods: {
getBookList() {
axios.get(`/books?page=${this.currentPage}&page_size=${this.pageSize}`)
.then(response => {
const {book_list: bookList, total} = response.data.result;
this.bookList = bookList;
this.bookTotal = total;
});
}
},
components: {
'page-bar': PageBar
}
}
</script>
<style scoped>
</style>
分页组件(子组件)
PageBar.vue:书单列表组件(父组件)
BookList.vue: