又來填坑了,今天來做翻頁,利用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的介紹,導致卡了飛哥半天的時間。
不要緊,飛哥就是趟雷的,今天又填了一個翻頁的坑,以後開發起來,會越來越快。