需求:
实现分页通过组件传参
实现
第一步:通过先不封装自己写出来效果(代码如下):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.pagination {
margin: 20px 0;
}
.pagination a {
padding: 5px 12px;
border: 1px solid #3ba9ff;
text-decoration: none;
margin: 5px;
}
.pagination a.active {
background: plum;
color: white;
}
</style>
</head>
<body>
<div id="app">
<ul>
<li v-for="user of showpag" :key="user.id">
{{user.name}}
</li>
</ul>
<div class="pagination">
<a href="javascript:;" @click="topre">上一页</a>
<a href="" v-for="(p,i) of getpag" @click.prevent="star=i" :class="{active:p===star+1}"> {{p}} </a>
<a href="javascript:;" @click="tonext">下一页</a>
</div>
</div>
</body>
<!-- <script src="js/vue.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
el: "#app",
data: {
// 数据
users: [
{ id: 1, name: '小单' },
{ id: 2, name: '小涛' },
{ id: 3, name: '小冯' },
{ id: 4, name: '小金' },
{ id: 5, name: '小宝' },
{ id: 6, name: '祥子' },
{ id: 7, name: '对的' },
{ id: 8, name: '谷歌' },
{ id: 9, name: '火狐' },
{ id: 10, name: '解决' },
{ id: 11, name: '原有' },
],
// 每页显示条数
strip: 2,
//刚开始的起始位置
star: 0
},
computed: {
getpag() {
//获取显示几页 数据的长度/每页显示个数
return Math.ceil(this.users.length / this.strip)
},
showpag() {
// 获取起始位置
let b = this.strip * this.star
return this.users.slice(b, this.strip + b)
}
},
methods: {
// 去下一页
tonext() {
if (this.star < this.getpag-1) {
this.star++;
}
},
// 去上一页
topre(){
if(this.star>0){
this.star--;
}
}
},
})
</script>
</html>
第二步:把按钮部分封装到组件中(代码如下)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.pagination {
margin: 20px 0;
}
.pagination a {
padding: 5px 12px;
border: 1px solid #3ba9ff;
text-decoration: none;
margin: 5px;
}
ul>li{
list-style: none;
}
.pagination a.active {
background: plum;
color: white;
}
</style>
</head>
<body>
<div id="app">
<ul>
<li v-for="user of showpag" :key="user.id">
{{user.id}}:{{user.name}}
</li>
</ul>
<paginates :getpag="getpag" :start="star" @fn="getfn"></paginates>
<paginates :getpag="getpag" :start="star" @fn="getfn"></paginates>
<paginates :getpag="getpag" :start="star" @fn="getfn"></paginates>
<paginates :getpag="getpag" :start="star" @fn="getfn"></paginates>
</div>
<template id="paginate">
<div class="pagination">
<a href="javascript:;" @click="topre">上一页</a>
<a href="" v-for="(p,i) of getpag" @click.prevent="toclick(i)" :class="{active:p===start1+1}"> {{p}} </a>
<a href="javascript:;" @click="tonext">下一页</a>
</div>
</template>
</body>
<!-- <script src="js/vue.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
//创建组件
Vue.component('paginates', {
template: "#paginate",
props: ['getpag', 'start'],
data() {
return {
start1: this.start,
}
},
methods: {
toclick(i) {
this.start1 = i
},
// 去下一页
tonext() {
if (this.start1 < this.getpag - 1) {
this.start1++;
}
},
// 去上一页
topre() {
if (this.start1 > 0) {
this.start1--;
}
}
},
updated() {
//因为子组件不能直接改变父组件传过来的值
//所以子组件数据改变后发送数据给父组件
this.$emit("fn", this.start1);
},
})
new Vue({
el: "#app",
data: {
// 数据
users: [
{ id: 1, name: '小单' },
{ id: 2, name: '小涛' },
{ id: 3, name: '小冯' },
{ id: 4, name: '小金' },
{ id: 5, name: '小宝' },
{ id: 6, name: '祥子' },
{ id: 7, name: '对的' },
{ id: 8, name: '谷歌' },
{ id: 9, name: '火狐' },
{ id: 10, name: '解决' },
{ id: 11, name: '原有' },
],
// 每页显示条数
strip: 3,
//刚开始的起始位置
star: 0
},
computed: {
getpag() {
//获取显示几页 数据的长度/每页显示个数
return Math.ceil(this.users.length / this.strip)
},
showpag() {
// 获取起始位置
let b = this.strip * this.star
return this.users.slice(b, this.strip + b)
}
},
methods: {
getfn(n) {
this.star = n
}
},
})
</script>
</html>
问题
通过封装到组件中会发现一个问题:
父组件传给子组件中的数据不能在子组件中直接修改
解决方法:
1:通过组建通信子传父:
this.$emit("fn", this.start1);
来告诉父组件你要修改的属性值
2:通过修饰符.sync
(为了解决子组件要修改父组件中的数据而演变出来的方法)
代码如下:(上边的代码直接修改的)
//父组件中使用的组件
<paginates :start.sync="star" @fn="getfn"></paginates>
//js代码子组件触发的事件
mounted(){
this.$emit("updeate:start", this.start1);
}