又来填坑了,今天来做翻页,利用element-plus框架,翻页组件很快就做好了。
效果不错,看看element-plus 官方文档,调用current-change事件处理翻页方法就可以了。
<el-pagination
small
class="mt-4"
background
layout="prev, pager, next"
:page-size="num"
:total="Number(pageCount)"
@current-change="handleCurrentChange"
>
</el-pagination>
貌似没有什么难度。
const handleCurrentChange = (val) => {
console.log(`current page: ${val}`)
router.push(`/meeting/answer/${val}`)
}
直接暴力更换路由参数
哇塞,好简单,奇怪为啥列表组件不更新呢。一定是哪里有问题,去查查Vue-Router 文档,是不是router.push方法写的不对。
的确发现,有这么一段,说Vue高效利用组件,如果只是单纯的路由参数改变,列表组件不会刷新,被高效复用了。并给出了解决办法
就是在created的生命周期中,采用watch监听路由route.params参数,发现变化,就重新异步获取新数据,赋值给列表子组件。
好嘞,按照官方说的办,但是Vue3没有created什么周期。我们就在OnMounted生命周期中把watch加上。照着官方抄,一定行。
onMounted(()=>{
watch(()=>route.params,()=>{
getlist();//axios获取数据函数
},{immediate: true})
})
watch监听的写法,简单说一下
watch(参数1,参数2,参数3);
参数1:被监听的值。
参数2:监听到参数1变化后,要执行的回调。
参数2有两个参数,
(小参数1,小参数2)=>{
//todo...
}
小参数1:监听到参数1的新值,
小参数2:监听参数1的旧值。
参数3:是watch的一些参数
watch(()=>route.params,()=>{
getlist();
},{immediate: true})
上面代码具体是,watch监听了路由参数,有变化就去执行回调,获取数据,最后的参数就是,监听初始化后立刻执行。
看一下console.log,哦也,数据更新了呢。看来是要仔细看看官方文档,等等,为什么我的列表还是不更新翻页?
<questionItem v-for="(answer, index) in answers" :answer="answer" :key="index" />
我把列表的每一行数据单独做了一个组件,并用v-for赋值,为啥呢。难道是watch写的不对,查查查查,我晕,我很晕,但我忽然想起来v-for循环有一个重要的东西,他就是key,我上面的代码,循环的时候,图省事,就把index帮给了key,这样获取的数据,不管怎么变,index都是从0-20数一遍。
<questionItem v-for="(answer, index) in answers" :answer="answer" :key="answer.answerid" />
把key绑定改为了数据id,奇迹发生了!可以正常翻页了。哦也!
还发现一个小坑,看下面的代码,
我在路由文件中,代码如下,动态参数是page,“?”代表可以省略。
{
path: 'answer/:page?',
component: () => import('@/views/meeting/answer.vue'),
name: 'answer',
meta: { needLogin: true, title: 'answer', icon: 'answer' },
}
回到列表页,watch监控了当前路由的参数,只要页面参数有变化,就会刷新路由。
onMounted(()=>{
watch(()=>route.params,()=>{
getlist();//axios获取数据函数
},{immediate: true})
})
在列表页来回翻页,没有问题,都会重新加载页面,但是,当我们从别的页面,来到这一页,或从这一页离开,这两个过程我们能监控到的路由参数么?watch会不会也触发后面的方法呢?
答案是:会,必须会。
由于第一次进页面,url显示http://localhost:3000/answer/ ,路由参数page?,为可选参数,我并没有写page参数,所以page的值为''。
而离开页面的时候,page从过去的数值变成了的undefined
那watch监控到了page的从无到有,从有到无,触发watch的方法么?触发!当你离开这一页的时候,就会又一次请求数据。挺恶心,必须干掉这个bug。
上代码,if大法判断一下。
onMounted(()=>{
watch(()=>route.params.page,()=>{
if(route.params.page != undefined){
getlist();
}
console.log(route.params.page)
},{immediate:true})
})
终于完美了。如果高手能告诉飞哥更好的办法,请在评论区留言。
反思当初,第一,没有看明白watch的文档,更没看完整vue-router的文档,还有小小的v-for的介绍,导致卡了飞哥半天的时间。
不要紧,飞哥就是趟雷的,今天又填了一个翻页的坑,以后开发起来,会越来越快。