1、实现效果
简述:在日常开发中一个可扩充、复用的组件是必不可少的,我带着学习的心态,通过查询了一些同志的案例,下面将实现心得分享一下。
实现步骤
1、template解构
<template>
<div
class="page-nav"
style="-moz-user-select: none"
onselectstart="return false;"
>
<span
class="first nav-hover"
@click="onFirst"
:class="state.a ? 'disabled' : ''"
>{{ state.first }}</span
>
<font-awesome-icon
@click="onPrev"
class="angle nav-hover"
:class="state.b ? 'disabled' : ''"
icon="angle-left"
/>
<ul>
<li
v-for="(item, index) in state.list"
@click="buttonPage(item)"
:key="index"
:class="{ active: state.currentPage == item }"
>
{{ item }}
</li>
</ul>
<font-awesome-icon
@click="onNext"
class="angle nav-hover"
:class="state.c ? 'disabled' : ''"
icon="angle-right"
/>
<span
class="end nav-hover"
@click="onLast"
:class="state.d ? 'disabled' : ''"
>{{ state.last }}</span
>
<input
:value="state.value"
type="text"
placeholder="..."
@input="pageChange"
/>
<span class="nav-hover" @click="onJust">跳转</span>
</div>
</template>
这里我标签使用的随意一些,还引入了fontAwesome的一些东西,实现思路借鉴了其他人的东西,通过:class来激活禁用控件。主要的逻辑在js上。
2、script
<script setup>
import { ref, defineProps, defineEmits, onMounted, reactive } from "vue";
const props = defineProps({
config: Object,
});
const emit = defineEmits();
const state = reactive({
first: "首页",
last: "尾页",
a: false,
b: false,
c: false,
d: false,
page: 1,
pageSize: 10,
total: 0, //总数
list: [], //页数数组
currentPage: 1, //当前页
sumPages: 0, //算得页总数
recordPage: 0, //初始页数,
maxShowPage: 8, //item显示数
step: 4, //步数
value: 1,
input: 0,
});
onMounted(() => {
state.total = props.config.total;
state.pageSize = props.config.pageSize;
state.sumPages = Math.ceil(state.total / state.pageSize);
// 父组件拿到总数
emit("onCount", state.sumPages);
if (state.sumPages == 1) {
state.a = true;
state.b = true;
state.c = true;
state.d = true;
}
// 初始化pageList
state.sumPages >= state.maxShowPage
? (state.recordPage = state.maxShowPage)
: (state.recordPage = state.sumPages);
for (var i = 1; i <= state.recordPage; i++) {
state.list.push(i);
}
state.value = state.currentPage;
state.input = state.currentPage;
if (state.currentPage == 1) {
state.a = true;
state.b = true;
state.c = false;
state.d = false;
} else if (state.currentPage == state.sumPages) {
state.a = false;
state.b = false;
state.c = true;
state.d = true;
} else {
state.a = false;
state.b = false;
state.c = false;
state.d = false;
}
});
const countPages = (start, end) => {
state.list = [];
for (var i = start; i <= end; i++) {
state.list.push(i);
}
};
const pageChange = (val) => {
state.input = parseInt(val.target.value);
};
const onJust = () => {
if (state.input <= state.sumPages && state.input > 0 && state.input != NaN) {
buttonPage(state.input);
} else {
state.value = "";
}
};
const onFirst = () => {
buttonPage(1);
};
const onPrev = () => {
if (state.currentPage > 1) {
buttonPage(state.currentPage - 1);
}
};
const onNext = () => {
if (state.currentPage < state.sumPages) {
buttonPage(state.currentPage + 1);
}
};
const onLast = () => {
buttonPage(state.sumPages);
};
const buttonPage = (val) => {
if (val == 1) {
state.a = true;
state.b = true;
state.c = false;
state.d = false;
countPages(1, state.recordPage);
} else if (val == state.sumPages) {
state.a = false;
state.b = false;
state.c = true;
state.d = true;
// 限制最大页比最大显示数小的情况
state.sumPages > state.maxShowPage
? countPages(state.sumPages - state.maxShowPage, state.sumPages)
: countPages(1, state.sumPages);
} else {
if (val <= state.maxShowPage) {
countPages(1, state.recordPage);
} else if (val >= state.maxShowPage) {
(val <= state.sumPages- state.step)?
countPages(val-state.step, val+state.step):
countPages(state.sumPages-state.maxShowPage, state.sumPages)
}
state.a = false;
state.b = false;
state.c = false;
state.d = false;
}
state.value = val;
state.currentPage = val;
state.input = val;
emit("onMyClick", val);
};
</script>
vue3已经高度的提供了函数式编程,可以看出来我们的代码具有高独立性,就是逻辑有些臃肿,因为我的vue水平也是在入门,我们写的是一个子组件,要靠父组件的传参来执行效果
<pageNavVue :config="state.pageConfig" @onCount="pageCount" @onMyClick="pageClick"></pageNavVue>
import { reactive } from "vue";
const state = reactive({
pageConfig: {
total: 15,
pageSize: 7,
},
nowPage:'1',
countPage:"x"
});
const pageClick=(val)=>{
state.nowPage=val;
}
const pageCount=(val)=>{
state.countPage=val;
}
这里还包含了一些子父组件交互的方法。
3、css-scss
<style scoped lang="scss">
.table {
width: 100%;
text-align: left;
margin-top: 3rem;
tr{
th{
color: cadetblue;
padding: 1rem;
}
td{
padding: 1rem;
border-top: 1px solid rgba(0,0,0,.12);
border-bottom: 1px solid rgba(0,0,0,.12);
box-sizing: border-box;
a{
display: inline-block;
padding: .5rem;
color: rgb(248, 29, 29);
border-radius: 3rem;
margin-right: .5rem;
cursor: pointer;
font-size: 1.5rem;
&:active{
background-color: rgba($color: cadetblue, $alpha: .1);
}
}
}
.td-end{
color: cadetblue;
font-size: 1.5rem;
}
}
}
</style>
这是我第一次使用scss,我感受到了它带来的便捷,维护开发都变得easy
4、心得总结
实现难点无非就是js的逻辑控制,根据父组件传来的总条数和每页数量来求取页数。 配合vue的特性,我们使用几个关键的变量让工作执行起来,相信刚入门的同学和我一样,对于组件的理解不深刻,感想不敢做,敢做不会做,我的建议是向前看,只有不断的思考,磨练,吸收,我们才能具备一个开发人员的品质。
我想重点说下这几个参数,list数组是展示页数item的容器
list: [], //页数数组
currentPage: 1, //当前页
sumPages: 0, //算得页总数
recordPage: 0, //初始页数,
maxShowPage: 8, //item显示数
step: 4, //步数
currentPage,是当前选中页数,也是组件动态运行的关键
为什么要有recordPage,我的想法是简单直接的恢复list状态,当点击首页时
if (val == 1) {
state.a = true;
state.b = true;
state.c = false;
state.d = false;
countPages(1, state.recordPage); //直接还原了数组,
}
maxShowPage:如百度的分页组件可以发现,我们在左右点击时,item出现多个是体验友好的
直接多出4个,可以快速选择,我利用的思想就是通过计算重置list
const countPages = (start, end) => {
state.list = [];
for (var i = start; i <= end; i++) {
state.list.push(i);
}
};
关键的地方是怎么重置,如何界定数组
else if (val == state.sumPages) {
state.a = false;
state.b = false;
state.c = true;
state.d = true;
// 到尾页时,这里会有俩种情况,一个是总页数达不到maxShowPage,这个时候就是直接数组countPages(1, state.sumPages),如果是够maxShowPage,那么就是sumPages到它的前maxShowPage这几个数
state.sumPages > state.maxShowPage
? countPages(state.sumPages - state.maxShowPage, state.sumPages)
: countPages(1, state.sumPages);
} else {
// 不是尾页时,这里会有3种情况,一个是向左点击,<最大页,直接数组,countPages(1, state.recordPage),第二个是向右点击超出8,那么数组的限定就得改变countPages(val-state.step, val+state.step),第三种情况,数组的尾端只能限定在总页数减去步长的地方,否则数组就错误了。
if (val <= state.maxShowPage) {
countPages(1, state.recordPage);
} else if (val >= state.maxShowPage) {
(val <= state.sumPages- state.step)?
countPages(val-state.step, val+state.step):
countPages(state.sumPages-state.maxShowPage, state.sumPages)
}
state.a = false;
state.b = false;
state.c = false;
state.d = false;
}
这样写下来我也感觉不难,可是在做的时候确实苦思了一会儿,因为自己的整体能力还是有待提升的,记录在这里,谢谢阅读!