最近利用時間做了一個 Vuetify 的 side project
一邊問著 google 大神,一邊慢慢實作自己的想法
竟然也讓我做出一個不錯用的 IG 照片閱覽功能
基本上就是憑著寫 Android 的概念
配合 Vuetify 的官網 Document
還有 W3CSHOOL 的基礎知識,慢慢湊起來的
實在不懂的時候問一下公司的前端高手,也是一帖特效藥
=== 問題開始 ===
因為寫 APP 的時候也用 Firebase 的 Firestore
所以自然而然就想說 DB 就用 Firestore
除了熟悉之外,也是滿方便的
但最近在使用的時候發生了一些問題
是 Firestore 使用不當造成的
我在切換照片的時候
會先閃出 a照片,再 show b 照片
而且一開始不會有事
要到有幾次換頁面 (跳頁) 才會發生
重點是,只有在 safari 出現,chrome 不會
一直聽說前端 browser 很多坑
沒想到剛入新手村的我就這樣被 safari 搞了一次
我看著 log 發現我的 photo 物件被 DB 塞了兩次值
難怪會有切一次照片,跳兩次的情況
由於 Firestore 支援即時更新
也就是說我如果在另一個裝置上增加了照片 or 評論
其餘的裝置會同步的收到,並更新
或是我的 Python 爬蟲抓內容的時候,也會同步更至最新
要做到這件事,我們就必需和 Firestore 建立一條不斷的連線
讓內容能持續的被更新
現在這種情況很明顯就是連線被監聽了兩次
我們有了兩條不斷的連線
為什麼偏偏只有 safari 會有這個情況呢?
上網 google 後發現其它人也有遇過
大多是 safari 的 cache 機制造成的
我們 A 頁起了一個連線,跳到 B 頁後再回 A 頁
這樣第二次的 A 頁 cache 保存了舊連線並建立了新連線
造成共存的情況
那要怎麼解呢?
我想了好幾個方法,試了很多次
最後得出 3 個解法
1、不要建立不斷連線、使用 Firestroe once getting 的 function
2、使用 Javascript 的 window.addEventListener 監聽 event
3、使用 Vue 的 beforeDestroy 在頁面跳出前,做取消訂閱 Firestore 的動作
第一種如果有特別需要保持更新的人
可能就沒辦法使用,在此不推薦
第二種的做法就像這樣
window.addEventListener('popstate', function(event))
popstate 是一個 history 下的 event
只會在 history entry 變動時被 trigger
也就是說,不論跳頁、上一頁、下一頁…等
都會改變到 history entry 而觸發
這樣雖然可以達到目的
不過會造成很多額外的觸發,這邊也較不推薦
這裡有 window 的 event 大全
若有特別需要的人,可以來這邊找找有沒有適合的 event 可用
最後的第三種
是利用 Vue Component 的生命週期來處理,如下圖
這個有點像 Android Activity Lifecycle 一樣
Vue 也有類似的 create ~ destroy 等狀態
比如說我們的 Firestore 連線就是在 created 建立的,如下
export default { components: {}, data: () => ({ photo: Object, dbUnsubscribe: Object }), methods: { dbUnsubscribeFunc() { // 終止 db 連線 this.dbUnsubscribe(); } }, computed: {}, created() { // 建立 db 連線 this.queryShowPhotoByAcc(); } };
所以我們可以利用生命周期的 beforeDestroy
來達到我們的目的
不過 beforeDestroy 只能監聽到頁面跳換
無法監聽到頁面刷新和關閉標籤頁。
若是想要監聽的話,就要用方法二的 onbeforeunload event 了
好,最後,我們利用 beforeDestroy 把 code 改成下面這樣
created() { // 建立 db 連線 this.queryShowPhotoByAcc(); }, beforeDestroy() { this.dbUnsubscribeFunc(); }
完成!!!
想了解更多的生命週期可以看這裡
資料來源:
https://vuetifyjs.com/en/getting-started/quick-start
https://developer.mozilla.org/en-US/docs/Web/API/Window#Events
https://vuejs.org/v2/guide/instance.html
留言列表