基于vue写出的分页组件
分页组件是一种用户界面元素,用于在长列表或数据集中分割内容。它通常用于网页、移动应用或其他软件界面中,以便用户能够按页浏览内容。 分页组件是每个开发人员必须掌握的一个组件,广泛应用在各个场所。用以用户方便阅读等。
组件说明
变量颜色
@danger: #cc3600;
@primary: #6b9eee;
@words: #373737;
@lightWords: #999;
@warn: #dc6a12;
@success: #7ebf50;
@gray: #b4b8bc;
@dark: #202020;
属性名 | 含义 | 类型 | 必填 | 默认值 |
---|---|---|---|---|
current | 当前页码 | Number | 否 | 1 |
total | 总数据量 | Number | 否 | 0 |
limit | 页容量 | Number | 否 | 10 |
visibleNumber | 可见页码数 | Number | 否 | 10 |
事件名 | 含义 | 事件参数 | 参数类型 |
---|---|---|---|
pageChange | 页码变化 | 新的页码 | Number |
基本样式
新建一个Page.vue,在template写入基本模板,通过a标签(当然也可以用其他的),写出基本模板,同时加入点击事件和css样式和一些动态样式,用:class来绑定动态css类,同时要注意,只有当页码数大于一的时候才会用到这个组件,否则毫无意义,同时要注意,子组件不能更改父组件要用的数据,以免出现错误 定义了一个active为加粗颜色,方便确定当前位置,通过vfor根据生成的数组循环生成a标签
<template>
<!-- //只有总页数大于1的时候才会显示,比较稳定,选择用vif否则没有意义 -->
<div class="pager-container" v-if="pageNumber > 1">
<!-- 子组件无权更改数据,在父组件中数据更改可能会影响到其他,所以子组件只能通过发出通知的形式告诉父组件 -->
<!-- 点击的时候调用h函数,传入适当的参数,大返回就传入第一页,小返回就传入当前页数-1 -->
<!-- 注意a标签没有href,如果写上了就会存在重新加载页面的问题 -->
<a @click="handleClick(1)" :class="{ disabled: current === 1 }"
>|<<</a
>
<a
@click="handleClick(current - 1)"
:class="{ disabled: current === 1 }"
><<</a
>
<!-- 循环生成的数组,设置唯一值,并且判断添加active样式(当前页是否为) -->
<!-- 当前页是多少就传入多少 -->
<a
@click="handleClick(tem)"
v-for="(tem, i) in numbers"
:key="i"
:class="{ active: tem === current }"
>{{tem}}</a
>
<a
@click="handleClick(current + 1)"
:class="{ disabled: current === pageNumber }"
>>></a
>
<a
@click="handleClick(pageNumber)"
:class="{ disabled: current === pageNumber }"
>>>|</a
>
</div>
</template>
基本样式设置(less)
<style lang="less" scoped>
@import "../styles/var.less";
.pager-container {
display: flex;
justify-content: center;
margin: 20px 0;
a {
color: @primary;
margin: 0 6px;
cursor: pointer;
&.disabled {
color: @lightWords;
cursor: not-allowed;
}
&.active {
color: @words;
font-weight: bold;
cursor: text;
}
}
}
</style>
导出部分
计算属性部分: 写入了四个计算函数,分别是pageNumber用来得到一共分成了多少页(Math.ceil(this.total / this.limit); //总条数/每页限制10条 得到页数)getMin(),getMax()得到当前展示页最大的那一个和最小那一个页数
计算方法:min()this.current - Math.floor(this.visibleNumber / 2);//当前页面减去最多显示页码数的一半得到显示最小的那个
max()this.getMin + this.visibleNumber - 1;最小值+当前页面最多显示几个页码-1得到最大的那个页码
numbers():通过构建一个数组,对数组里面添加页数,通过for循环从最小到最大,往里面添加数字形成数组(注意:每次转跳都会重新渲染页面,所以min和max都会不断变化,数组的值也会不断变化)
方法部分methods部分:
handleClick(newPage)方法抛出事件并且通知父组件,因为 子组件无权更改数据,在父组件中数据更改可能会影响到其他,所以子组件只能通过发出通知的形式告诉父组件
- this.$emit 是 Vue 实例提供的方法,用于触发自定义事件并通知父组件。
- “pageChange” 是自定义事件的名称,可以根据具体情况自定义命名。
- newPage 是要传递给父组件的新页码数据。
- 通过这段代码,当用户点击分页组件的页面导航按钮时,会通过触发自定义事件的方式通知父组件发生了页码的变化,父组件则可以根据新的页码进行相应的处理,例如重新加载对应页码的数据或更新UI等。
props:部分:
<script>
export default {
computed: {
pageNumber: function () {
return Math.ceil(this.total / this.limit); //总条数/每页限制10条 得到页数
},
getMax() {
let max = this.getMin + this.visibleNumber - 1;
if (max > this.pageNumber) {
max = this.pageNumber;
}
return max;
},
getMin() {
//得到显示页码中最小的数字
//当前页面减去最多显示页码数的一半得到显示最小的那个
let min = this.current - Math.floor(this.visibleNumber / 2);
if (min < 1) {
min = 1;
}
return min;
},
numbers() {
let arr = [];
for (let i = this.getMin; i <= this.getMax; i++) {
arr.push(i);
}
return arr;
},
},
methods: {
handleClick(newPage) {
//如果新页面小于1则赋值为1,大于最大的页数则赋值为最大页数,等于当前页数直接return
if (newPage < 1) {
newPage = 1;
}
if (newPage > this.pageNumber) {
newPage = this.pageNumber;
}
if (newPage === this.current) {
return;
}
//抛出事件通知父组件
//参数:名字,数据
this.$emit("pageChange", newPage);
},
},
props: {
current: {
//当前页
type: Number,
default: 1,
},
total: {
//总条数
type: Number,
default: 0,
},
limit: {
//每页展示多少条
type: Number,
default: 10,
},
// 最多显示页码的个数
visibleNumber: {
type: Number,
default: 10,
},
},
};
</script>
组件部分到此为止,接下里是导入部分
app.vue
import Pager from "./components/Page.vue"引入组件,并且通过 components: {Pager, },注册组件
模板中写入自定义的组件,通过total传入总页数,current传入当前页数,点击调用子组件抛出的事件交由父组件执行,在methods:总定义了新的方法handlePageChange传入新页码,让当前页面变成新页
最后data()方面传入了基本数值
$event
是一个预留的特殊变量,用于传递事件对象或其他数据给事件处理函数。@pageChange
是监听自定义事件,当自定义事件被触发时,Vue 会自动将事件对象作为参数传递给事件处理函数。而 $event
则是用于接收这个事件对象的特殊变量。你可以自由选择处理函数的形参名称,例如这里使用了 $event
,也可以使用其他名称,如 event
、e
等。
<template>
<div>
<Pager
:total="total"
:current="current"
@pageChange="handlePageChange($event)"
></Pager>
</div>
<!-- <h1 v-if="score>=80">U</h1>
<h2 v-else-if="score>=60">L</h2>
<h3 v-else>X</h3> -->
<!-- vif会添加和删除元素,控制是否生成对应的dom,而vshow始终都会生成dom用dom控制style:display:none,vif则是直接删除元素 -->
<!-- 使用vif可以有效的减少树的节点和渲染量,但是也会导致树的不稳定,而vshow可以保持数的稳定,但不能减少树的节点和渲染量 -->
<!-- 因此,在实际开发中,显示频繁变化的情况下应该用vshow,用以保持树的稳定,显示状态变化少的时候用vif,用以减少树的节点和渲染量 -->
</template>
<script>
import Pager from "./components/Page.vue";
export default {
components: {
Pager,
},
methods: {
handlePageChange(newPage) {
this.current = newPage;
},
},
data() {
return {
current: 1,
total: 302,
};
},
};
</script>
<style scoped>
.iconfont {
font-size: 90px;
color: black;
}
</style>
总结:
该组件中需要注意的部分 一是vif和vshow区别,这一是面试题常考的 vif会添加和删除元素,控制是否生成对应的dom,而vshow始终都会生成dom用dom控制style:display:none,vif则是直接删除元素 使用vif可以有效的减少树的节点和渲染量,但是也会导致树的不稳定,而vshow可以保持数的稳定,但不能减少树的节点和渲染量因此,在实际开发中,显示频繁变化的情况下应该用vshow,用以保持树的稳定,显示状态变化少的时候用vif,用以减少树的节点和渲染量 二是子组件无权更改数据,在父组件中数据更改可能会影响到其他,所以子组件只能通过发出通知的形式告诉父组件,于是出现了子组件抛出事件通知父组件要进行改变了,从而由父组件进行改变,并且重新渲染dom。通过点击调用handleClick(newPage)方法传入新页码参数,同时this.emit("pageChange",newPage);是Vue实例提供的方法,用于触发自定义事件并通知父组件。 //参数:名字,数据 抛出事件通知父组件还要注意这个特殊的预留变量 emit("pageChange", newPage);是 Vue 实例提供的方法,用于触发自定义事件并通知父组件。 //参数:名字,数据 抛出事件通知父组件 还要注意这个特殊的预留变量 emit("pageChange",newPage);是Vue实例提供的方法,用于触发自定义事件并通知父组件。 //参数:名字,数据 抛出事件通知父组件还要注意这个特殊的预留变量 event
是一个预留的特殊变量,用于传递事件对象或其他数据给事件处理函数。
@pageChange是监听自定义事件,当自定义事件被触发时,Vue 会自动将**事件对象作为参数传递给事件处理函数**。而
event‘ 则是用于接∗∗收这个事件对象的特殊变量∗∗。你可以自由选择处理函数的形参名称,例如这里使用了 ‘event` 则是用于接**收这个事件对象的特殊变量**。你可以自由选择处理函数的形参名称,例如这里使用了 `event‘ 则是用于接∗∗收这个事件对象的特殊变量∗∗。你可以自由选择处理函数的形参名称,例如这里使用了 ‘event,也可以使用其他名称,如
event、
e` 等。
ps:已上传gitee gitee.com/wu-canhua/p…
转载自:https://juejin.cn/post/7261885938086952997