最近做的某個項目有個文件預(yù)覽的需求待秃,該界面左側(cè)是文件的目錄樹,右側(cè)是預(yù)覽痹屹,預(yù)覽這部分是子路由章郁,其path
為/file/preview/:fileId
。點擊目錄樹的文件名痢掠,右側(cè)預(yù)覽的fileId
發(fā)生變化從而刷新預(yù)覽的內(nèi)容驱犹。因為預(yù)覽這塊還需要展示文件名稱等信息,所以包含文件名稱和文件id的數(shù)據(jù)是通過$route
的params
傳遞過來的足画。
因用戶可能在預(yù)覽界面做刷新操作雄驹,為了防止頁面刷新丟失詳情數(shù)據(jù),筆者使用了sessionStorage
來保存stringify
后的詳情數(shù)據(jù)淹辞。
這樣医舆,在用戶首次進入預(yù)覽頁面時會觸發(fā)beforeRouteEnter
鉤子,在此鉤子函數(shù)里象缀,sessionStorage
是否有保存該fileId
的詳情數(shù)據(jù)蔬将,有則直接使用,沒有的話則將to.params
中的詳情數(shù)據(jù)保存到sessionStorage
中央星,并將詳情數(shù)據(jù)保存在組件的data
里霞怀。
當(dāng)用戶點擊目錄樹查看其他文件時,beforeRouteEnter
鉤子不會觸發(fā)了莉给,而是觸發(fā)beforeRouteUpdate
鉤子函數(shù)毙石,其處理邏輯同上。
這樣寫看著邏輯很清晰明了了颓遏,其主要代碼如下:
beforeRouteEnter (to, from, next) { // 首次進入此路由會觸發(fā)該鉤子函數(shù)
next(vm => {
if (!sessionStorage.getItem('scan_' + to.params.fileId)) {
sessionStorage.setItem('scan_' + to.params.fileId, JSON.stringify(to.params))
}
vm.details = JSON.parse(sessionStorage.getItem('scan_' + to.params.fileId))
})
},
beforeRouteUpdate (to, from, next) { // fileId發(fā)生改變時觸發(fā)此鉤子函數(shù)
if (!sessionStorage.getItem('scan_' + to.params.fileId)) {
sessionStorage.setItem('scan_' + to.params.fileId, JSON.stringify(to.params))
}
this.details = JSON.parse(sessionStorage.getItem('scan_' + to.params.fileId))
next()
},
data () {
return {
details: {} // 預(yù)覽相關(guān)的詳情數(shù)據(jù)
}
}
如果一切順利的話徐矩,筆者也不會如此大費周章來記錄這個所謂beforeRouteUpdate遇到的坑了。
當(dāng)筆者自信滿滿的點擊第一個文件預(yù)覽時叁幢,正常顯示滤灯!
OK,沒問題曼玩!
點擊第二個文件預(yù)覽鳞骤,它不顯示文件!
What is the problem?!
唉演训,遇到bug再正常不過了o(╥﹏╥)o弟孟,開始調(diào)試吧~
在beforeRouteUpdate
里打印details
的值,發(fā)現(xiàn)其正常顯示样悟,但devtools
里的details
卻是空的拂募!
這就奇了怪了!
details
的值被誰清空了呢窟她?
各種折騰無果后陈症,筆者突然將目光放在了data
函數(shù)上,這貨定義的details
的值為{}
震糖,該不會是它搞的鬼吧录肯!
抱著試試看的心態(tài)分別在beforeRouteUpdate
和data
函數(shù)中做了標(biāo)記,發(fā)現(xiàn)data
函數(shù)竟然后于beforeRouteUpdate
執(zhí)行吊说。
先執(zhí)行beforeRouteUpdate
论咏,再執(zhí)行data
优炬。
這也就能解釋為什么無法預(yù)覽文件了。
知道原因那就好解決了厅贪,筆者將代碼改動如下:
beforeRouteEnter (to, from, next) {
next(vm => {
if (!sessionStorage.getItem('scan_' + to.params.fileId)) {
sessionStorage.setItem('scan_' + to.params.fileId, JSON.stringify(to.params))
}
vm.details = JSON.parse(sessionStorage.getItem('scan_' + to.params.fileId))
})
},
beforeRouteUpdate (to, from, next) {
if (!sessionStorage.getItem('scan_' + to.params.fileId)) {
sessionStorage.setItem('scan_' + to.params.fileId, JSON.stringify(to.params))
}
next()
},
data () {
let details = sessionStorage.getItem('scan_' + this.$route.params.fileId)
if (details) {
details = JSON.parse(details)
}
return {
details: details || {}
}
}
這樣文件就能夠正常預(yù)覽了蠢护!