《Vue3小白填坑记》点击翻页,更新路由为啥内容列表不变化?

又来填坑了,今天来做翻页,利用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的介绍,导致卡了飞哥半天的时间。

不要紧,飞哥就是趟雷的,今天又填了一个翻页的坑,以后开发起来,会越来越快。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章