如何在 Vue3 中使用 pwa (Chrome)

其實 PWA 在哪個框架中使用,都沒有太大的差異,但是往往這一行 code 到底要放哪裡,我就是不知道啊XDD

最近的專案剛好都是用 vue3 來實作,自然要把 pwa 放進去 vue3 中也勢必要來解一篇紀錄一下,不然下次就又忘記了。

 

PWA可以幹嘛?

大家應該都有用過一個功能就是,你看到一個很喜歡的網站,你想把他加入手機主畫面或電腦桌面變成一個很像應用程式的icon,然後你點開他,他還是老樣子先打開瀏覽器,然後進入該網站。他就是幫你省了「打開瀏覽器」、「輸入網址」這兩個動作;當然還有其他很好的功用,像是離線預載入畫面bla bla之類的,但最主要解決一些人已經有網站,然後又想讓一些用戶方便提升黏著度的人在使用的(我覺得拉)。

你可能還是不知道那是啥,看以下圖片就知道:

vue3 使用 pwa - penueling.com
vue3 使用 pwa

就是右上角會出現視窗問你要不要把這個網頁安裝到你電腦(手機)呀?

如果你按下「安裝」,他就會出現在你的「應用程式」中:(抱歉應用程式有點亂XD 看最後一個)

點下去那個應用程式之後,他會依照你當初包成pwa的時候的設定檔設定的方式去打開網頁,通常你都要包成 pwa 了,大家都會選擇讓他新開視窗,然後隱藏所有瀏覽器的工具,看起來就真的很像應用程式囉!

(上面那個黃色的 bar 你也可以改成你喜歡的顏色)

 

大綱

首先你要打包專案成pwa的話,你會經歷以下幾件事:

  1. 撰寫 manifest.json
  2. 撰寫 serviceWorker.js
  3. 製作 icon 圖片
  4. index.html中引入
  5. 主動觸發詢問是否加入應用程式(可忽略這步)

 

撰寫 manifest.json

這邊介紹一個網站可以幫你寫(其實也沒啥大不了,自己寫也是可以)

填上你的資訊:

  1. App name:就是專案名稱全名
  2. Short Name :顯示在應用程式的名稱(icon下面),可以短一點。
  3. Background Color、Theme Color:可以改成你的主題色,背景色就是會像我那樣黃黃的那塊顏色。
  4. Display Mode:選Standalone或fullscreen都可以~ 看起來比較像應用程式
  5. 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 好像不是非常支援在每個裝置跟瀏覽器的喔!所以製作之前都要先查一下。

先醬~

學習程式原來可以這麼簡單:六角學院線上課程

初學者如何成為vue前端工程師:查看課程內容

---------------------------

| 軟體開發 | 網站建置 | 網頁系統 | 資料庫網站 |

| 客製化網站 (報名系統、投票系統、掛號系統...) |

| 前後端技術合作 |

歡迎與我們聯繫:jessica@penueling.com

加入Line立即聊聊:@539mjyid

1+
0 回復

發表評論

Want to join the discussion?
Feel free to contribute!

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。