文章大綱
其實 PWA 在哪個框架中使用,都沒有太大的差異,但是往往這一行 code 到底要放哪裡,我就是不知道啊XDD
最近的專案剛好都是用 vue3 來實作,自然要把 pwa 放進去 vue3 中也勢必要來解一篇紀錄一下,不然下次就又忘記了。
PWA可以幹嘛?
大家應該都有用過一個功能就是,你看到一個很喜歡的網站,你想把他加入手機主畫面或電腦桌面變成一個很像應用程式的icon,然後你點開他,他還是老樣子先打開瀏覽器,然後進入該網站。他就是幫你省了「打開瀏覽器」、「輸入網址」這兩個動作;當然還有其他很好的功用,像是離線預載入畫面bla bla之類的,但最主要解決一些人已經有網站,然後又想讓一些用戶方便提升黏著度的人在使用的(我覺得拉)。
你可能還是不知道那是啥,看以下圖片就知道:
就是右上角會出現視窗問你要不要把這個網頁安裝到你電腦(手機)呀?
如果你按下「安裝」,他就會出現在你的「應用程式」中:(抱歉應用程式有點亂XD 看最後一個)
點下去那個應用程式之後,他會依照你當初包成pwa的時候的設定檔設定的方式去打開網頁,通常你都要包成 pwa 了,大家都會選擇讓他新開視窗,然後隱藏所有瀏覽器的工具,看起來就真的很像應用程式囉!
(上面那個黃色的 bar 你也可以改成你喜歡的顏色)
大綱
首先你要打包專案成pwa的話,你會經歷以下幾件事:
- 撰寫
manifest.json - 撰寫
serviceWorker.js - 製作 icon 圖片
- 在
index.html中引入 - 主動觸發詢問是否加入應用程式(可忽略這步)
撰寫 manifest.json
這邊介紹一個網站可以幫你寫(其實也沒啥大不了,自己寫也是可以)
填上你的資訊:
- App name:就是專案名稱全名
- Short Name :顯示在應用程式的名稱(icon下面),可以短一點。
- Background Color、Theme Color:可以改成你的主題色,背景色就是會像我那樣黃黃的那塊顏色。
- Display Mode:選Standalone或fullscreen都可以~ 看起來比較像應用程式
- Start URL:index.html
好的你都設定好之後,右邊就換直接看到他幫你寫好的json,複製起來,然後在public資料夾下面(跟index.html同一層就對了)建立一個檔案叫做manifest.json,把剛剛複製的json貼進去。
--public
--index.html
--favicon.ico
--manifest.json
這時候你的manifest.json應該長得類似這樣:
{
"name": "penueling",
"short_name": "penueling",
"theme_color": "#f85758",
"background_color": "#f85758",
"display": "fullscreen",
"scope": "/",
"start_url": "index.html",
}
還沒結束,你還缺少icon圖片的設定!
在最下面新增一個 key 叫做icons,然後指定他的圖片位置和大小:
你要在電腦用的話,至少一定要有144的。
{
//...
"icons": [
{
"src": "logo72x72.png",
"type": "image/png",
"sizes": "72x72"
},
{
"src": "logo96x96.png",
"type": "image/png",
"sizes": "96x96"
},
{
"src": "logo144x144.png",
"type": "image/png",
"sizes": "144x144"
}
]
}
撰寫 serviceWorker.js
新增一隻檔案在public資料夾下面,叫做serviceWorker.js
--public
--index.html
--favicon.ico
--manifest.json
--serviceWorker.js
內容如下:
const cacheName = "penueling";
self.addEventListener("install", e => {
e.waitUntil(
caches.open(cacheName).then(cache => {
return cache.addAll(["/", "/index.html", "/manifest.json"]);
}),
);
});
self.addEventListener("fetch", event => {
event.respondWith(
caches
.open(cacheName)
.then(cache => cache.match(event.request, { ignoreSearch: true }))
.then(response => {
return response || fetch(event.request);
}),
);
});
製作 icon 圖片
看到上面的manifest.json應該就知道你要準備哪幾種尺寸的圖片了吧!
記得一樣要放在public資料夾下面。
--public
--index.html
--favicon.ico
--manifest.json
--serviceWorker.js
--logo72x72.png
--logo96x96.png
--logo144x144.png
在 index.html中引入
重頭戲來了,這邊就是把剛剛建立的檔案都引入才會有作用~
<head>
//...
<link rel="manifest" href="/manifest.json" />
<script>
if ("serviceWorker" in navigator) {
navigator.serviceWorker
.register("/serviceWorker.js")
.then(res => console.log("service worker registered"))
.catch(err => console.log("service worker not registered", err));
}
</script>
</head>
這時候,啟動你的專案,已經可以看到可以加入 pwa 的按鈕囉,點下去就會跳出確認視窗。

如果你加入後,打開你的應用程式,重新整理發現他一片空白,不要緊張~ 因為你的應用程式最終應該是會用production環境去打包,所以開發環境會出現router錯誤是正常的喔!
主動觸發詢問是否加入應用程式
到這邊你的 pwa 就已經包好囉,可是我們一般使用者不會自己閒閒沒事去點右上角那個按鈕啊,看起來就不是什麼吸引人的東西XD
所以我們這邊可以在網頁中自己找地方觸發,你可以做一漂漂亮亮的banner或按鈕,鼓勵大家加入你的 pwa 應用程式。
為什麼一定要做成按鈕呢? 因為加入提示那個方法,只能觸發在點擊事件,你自己把他呼叫在 onMounted 裡他是會跳錯誤的!厲害了吧~
我這邊示範把它放在App.vue裡面,你也可以自己決定要放在哪一頁,哪顆按鈕。
import { reactive, onMounted } from "vue";
setup() {
const states = reactive({
deferredPrompt: null,
});
onMounted(() => {
window.addEventListener("beforeinstallprompt", e => {
e.preventDefault();
states.deferredPrompt = e;
});
window.addEventListener("appinstalled", () => {
states.deferredPrompt = null;
});
document.querySelector("#app").addEventListener("click", () => {
if (states.deferredPrompt) {
states.deferredPrompt.prompt();
states.deferredPrompt = null;
}
});
});
}
可以看到,我在onMounted的時候,把那個提示的 function 放到我的reactive狀態裡,之後可以直接 states.deferredPrompt.prompt();呼叫,就會跳出詢問你要不要加入的視窗。
然後我設定是點擊id=app的時候觸發詢問,也就是說你進到我的網頁,只要隨便點一下我就會先問你要不要加入XDD (好干擾啊)
最後上網查了一下,pwa 好像不是非常支援在每個裝置跟瀏覽器的喔!所以製作之前都要先查一下。
先醬~








發表評論
想要加入討論嗎?請盡情發表您的想法!