日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

手把手教你制作一个PWA应用教程

發(fā)布時間:2024/3/24 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 手把手教你制作一个PWA应用教程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.


來源 |?https://segmentfault.com/a/1190000019414253



簡介

Web前端的同學(xué)是否想過學(xué)習(xí)應(yīng)用開發(fā),以彌補(bǔ)自己的移動端能力的不足?但在面對一眾的選擇時很多同學(xué)略感迷茫,是學(xué)習(xí)ios還是android開發(fā)?是學(xué)習(xí)原生開發(fā),混合開發(fā)(例如:Ionic),還是使用react native或者flutter這樣的跨平臺框架?而應(yīng)用開發(fā)的學(xué)習(xí)周期長,學(xué)習(xí)成本高也讓一部分人望而卻步。

得益于前端技術(shù)的飛速發(fā)展,瀏覽器性能的不斷提高,使用網(wǎng)頁技術(shù)開發(fā)出接近原生體驗的應(yīng)用重新實現(xiàn)的現(xiàn)實,PWA就在這樣的背景下應(yīng)運(yùn)而生。可以用自己熟悉的HTML,CSS,Javascript開發(fā)出替代美原生應(yīng)用的網(wǎng)站,而擁有接近原生應(yīng)用的流暢程度,并且某些某些原生app才有的特性,

例如:a。可以在主屏上安裝應(yīng)用圖標(biāo),b。離線狀態(tài)下訪問,c。獲取消息通知,等等。。PWA的出現(xiàn)讓大家看到了希望!

對比原生應(yīng)用

那分別PWA和原生應(yīng)用比例到底有何競爭力呢?我們分別看一下原生應(yīng)用和PWA的特點:

原生應(yīng)用:

  • 使用原生SDK和開發(fā)工具開發(fā)

  • 需要考慮跨平臺,不同系統(tǒng)經(jīng)常需要獨(dú)立開發(fā)

  • 需要發(fā)布到應(yīng)用商店才能下載使用

  • 可以安裝到手機(jī)主屏,生成應(yīng)用圖標(biāo)

  • 直接運(yùn)行于操作系統(tǒng)上,訪問系統(tǒng)資源方便

  • 可以離線使用

  • 可以獲取消息通知

PWA應(yīng)用:

  • 使用HTML,CSS,JS開發(fā)

  • 無需考慮跨平臺,只需要考慮瀏覽器兼容性

  • 通過網(wǎng)址訪問,無需發(fā)布到應(yīng)用商店

  • 可以安裝到手機(jī)主屏,生成應(yīng)用圖標(biāo)

  • 運(yùn)行于瀏覽器中,可訪問系統(tǒng)資源

  • 可以離線使用

  • 可以獲取消息通知

可以發(fā)現(xiàn)PWA本質(zhì)上是原生應(yīng)用的主要能力,但是開發(fā)流程卻比原生應(yīng)用更加簡潔:

a、html / css / js的群眾基礎(chǔ)更好,開發(fā)效率更高;

b、省去了為不同系統(tǒng)開發(fā)獨(dú)立版本的大量成本;

c、省去了上架到應(yīng)用市場的繁瑣流程;

d、無需進(jìn)一步應(yīng)用商店下載,用戶使用起來也更加方便。但是稍微的是,PWA還是相對比較新的技術(shù),實現(xiàn)規(guī)范還有很多調(diào)整的空間,部分瀏覽器對PWA的支持也還不完善,但是PWA是一個趨勢,所以現(xiàn)在學(xué)習(xí)正合適!

本文將通過一個簡單的列子(一個簡單的郵編查詢應(yīng)用)向大家展示PWA的開發(fā)流程,項目參考:Traversy Media-使用Vue和Ionic4構(gòu)建PWA。完成后的效果是這樣的。

創(chuàng)建項目

項目使用Vue + Ionic的組合進(jìn)行開發(fā)。此處主要關(guān)注PWA的構(gòu)造,因此vue,ionic等技術(shù)不做過多描述。使用VSCode的同學(xué),建議安裝Vetur插件提高開發(fā)效率。

1.首先大致安裝@vue/cli:

npm install -g @vue/cli

2.初始化vue項目:

vue create vue-ionic-pwa

3.因為ionic的vue-router路由依賴于,所以接下來安裝vue-router:

vue add router

4.安裝?@ionic/vue

npm install @ionic/vue

5.在src/main.js中添加對ionic的

...import Ionic from '@ionic/vue'import '@ionic/core/css/ionic.bundle.css' Vue.use(Ionic)...

6.在src/router.js中使用IonicVueRouter替換預(yù)設(shè)的vue路由器:

import Vue from 'vue'import { IonicVueRouter } from '@ionic/vue';import Home from './views/Home.vue' Vue.use(IonicVueRouter) export default new IonicVueRouter({ mode: 'history', base: process.env.BASE_URL, routes: [ { path: '/', name: 'home', component: Home } ]})

7.將src/App.vue內(nèi)容修改為:

<template> <div id="app"> <ion-app> <ion-vue-router/> </ion-app> </div></template>

8.將src/views/Home.vue內(nèi)容修改為:

<template> <div class="ion-page"> <ion-header> <ion-toolbar> <ion-title> ZipInfo </ion-title> </ion-toolbar> </ion-header> <ion-content class="ion-padding">My App</ion-content> </div></template> <script>export default { name: 'home', components: {}}</script>

最后,我們運(yùn)行yarn serve看下效果:

App功能實現(xiàn)

App主要有三部分組成:1。搜索組件,用于輸入郵編并查詢,2。展示組件,用于展示查詢到的郵編信息,3。清除按鈕,用于清除查詢到的郵編信息

1、搜索組件

我們在src/components下面的新建ZipSearch.vue文件作為郵編搜索組件,主要邏輯為當(dāng)用戶輸入一串字符,點擊搜索按鈕,如果輸入合法則觸發(fā)get-zip事件,如果不合法則提示。

ZipSearch.vue

<template> <ion-grid> <form @submit="onSubmit"> <ion-col> <ion-item> <ion-label>ZipCode:</ion-label> <ion-input :value="zip" @input="zip = $event.target.value" name="zip" placeholder="Enter US ZipCode" /> </ion-item> </ion-col> <ion-col> <ion-button type="submit" color="primary" expand="block">Find</ion-button> </ion-col> </form> </ion-grid></template> <script>export default { name: "ZipSearch", data() { return { zip: "" }; }, methods: { onSubmit(e) { e.preventDefault(); const zipRegex = /(^\d{5}$)|(^\d{5}-\d{4}$)/; const isValid = zipRegex.test(this.zip); if (!isValid) { this.showAlert(); } else { this.$emit("get-zip", this.zip); } this.zip = ""; }, showAlert() { return this.$ionic.alertController .create({ header: "Enter zipcode", message: "Please enter a valid US ZipCode", buttons: ["OK"] }) .then(a => a.present()); } }};</script>

在src/views/Home.vue中約會ZipSearch組件,當(dāng)Home接收到get-zip事件時調(diào)用https://www.zippopotam.us的接口,獲取郵編對應(yīng)的信息:

... <ion-content class="ion-padding"> <ZipSearch v-on:get-zip="getZipInfo"/> </ion-content>... <script>import ZipSearch from "../components/ZipSearch"; export default { name: "home", components: { ZipSearch }, data() { return { info: null }; }, methods: { async getZipInfo(zip) { const res = await fetch(`https://api.zippopotam.us/us/${zip}`); if (res.status == 404) { this.showAlert(); } this.info = await res.json(); }, showAlert() { return this.$ionic.alertController .create({ header: "Not Valid", message: "Please enter a valid US ZipCode", buttons: ["OK"] }) .then(a => a.present()); } }};</script>

我們先看一下搜索組件的效果:

輸入郵編格式錯誤:

2、信息展示和清除組件

獲取到郵編信息后我們需要一個展示郵編信息的組件和一個src/components清除信息的按鈕,在下面新建ZipInfo.vue和ClearInfo.vue。

ZipInfo.vue

<template> <ion-card v-if="info"> <ion-card-header> <ion-card-subtitle>{{info['post code']}}</ion-card-subtitle> <ion-card-title>{{info['places'][0]['place name']}}</ion-card-title> </ion-card-header> <ion-card-content> <ion-list> <ion-item> <ion-label> <strong>State:</strong> {{info['places'][0]['state']}} ({{info['places'][0]['state abbreviation']}}) </ion-label> </ion-item> <ion-item> <ion-label> <strong>Latitude:</strong> {{info['places'][0]['latitude']}} </ion-label> </ion-item> <ion-item> <ion-label> <strong>Longitude:</strong> {{info['places'][0]['longitude']}} </ion-label> </ion-item> </ion-list> </ion-card-content> </ion-card></template> <script>export default { name: "ZipInfo", props: ["info"]};</script>

ClearInfo.vue

<template> <ion-button color="light" expand="block" v-if="info" @click="$emit('clear-info')">Clear</ion-button></template> <script>export default { name: "ClearInfo", props: ["info"]};</script>

接著在Home中約會ZipInfo和ClearInfo組件:

src / views / Home.vue

... <ion-content class="ion-padding"> <ZipSearch v-on:get-zip="getZipInfo"/> <ZipInfo v-bind:info="info"/> <ClearInfo v-bind:info="info" v-on:clear-info="clearInfo"/> </ion-content>... import ZipInfo from "../components/ZipInfo";import ClearInfo from "../components/ClearInfo"; export default { name: "home", components: { ZipSearch, ZipInfo }, methods:{ ... clearInfo(){ this.info = null; } }}

到此,app的主體就完成了,效果如下:

實現(xiàn)PWA

我們使用現(xiàn)成的@vue/pwa插件來給我們的app增加PWA的能力。

安裝@vue/pwa:

vue add @vue/pwa

安裝完成后項目中增加了public/manifest.json和registerServiceWorker.js兩個文件。其中public/manifest.json文件內(nèi)容如下:

{ "name": "vue-ionic-pwa", "short_name": "vue-ionic-pwa", "icons": [ { "src": "./img/icons/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" }, { "src": "./img/icons/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" } ], "start_url": "./index.html", "display": "standalone", "background_color": "#000000", "theme_color": "#4DBA87"}

manifest.json中主要包含app的基本信息,例如名稱(名稱),圖標(biāo)(圖標(biāo)),顯示方式(display)等等,是web app能被以類似原生的方式安裝,展示的必要配置。更多的配置項可參考MDN Web App清單。

在Chrome瀏覽器控制臺中也可看到app的manifest配置:

registerServiceWorker.js為注冊服務(wù)人員。服務(wù)人員通俗地說就是在瀏覽器后臺獨(dú)立于網(wǎng)頁運(yùn)行的一段腳本,服務(wù)人員可以完成一些特殊的功能,例如:消息推送,后臺同步,攔截和處理網(wǎng)絡(luò)請求,管理網(wǎng)絡(luò)緩存等。Serviceworker之于pwa的意義在于能夠為用戶提供離線體驗,即掉線狀態(tài)下用戶依舊能夠訪問網(wǎng)站并獲取已被緩存的數(shù)據(jù)。使用service worker需要HTTPS,并考慮瀏覽器兼容性。

registerServiceWorker.js

import { register } from 'register-service-worker' if (process.env.NODE_ENV === 'production') { register(`${process.env.BASE_URL}service-worker.js`, { ready () { console.log( 'App is being served from cache by a service worker.\n' + 'For more details, visit https://goo.gl/AFskqB' ) }, registered () { console.log('Service worker has been registered.') }, cached () { console.log('Content has been cached for offline use.') }, updatefound () { console.log('New content is downloading.') }, updated () { console.log('New content is available; please refresh.') }, offline () { console.log('No internet connection found. App is running in offline mode.') }, error (error) { console.error('Error during service worker registration:', error) } })}

在Chrome瀏覽器控制臺中也可看到服務(wù)工作者的狀態(tài):

當(dāng)然,只注冊了service worker還不夠,我們還希望控制service worker的行為,通過在vue.config.js中增加相關(guān)的配置我們可以設(shè)置service worker文件的名稱,緩存邏輯等等。

vue.config.js

module.exports = { pwa: { workboxPluginMode: 'GenerateSW', workboxOptions: { navigateFallback: '/index.html', runtimeCaching: [ { urlPattern: new RegExp('^https://api.zippopotam.us/us/'), handler: 'networkFirst', options: { networkTimeoutSeconds: 20, cacheName: 'api-cache', cacheableResponse: { statuses: [0, 200] } } } ] } }}

更多配置請參考:@ VUE / CLI-插件,PWA和針線-的WebPack-插件。由于@vue/cli-plugin-pwa,生成的服務(wù)人員只在生產(chǎn)環(huán)境生效,所以建議將項目建設(shè)之后部署到生產(chǎn)環(huán)境測試本文示例使用GitHub的頁面進(jìn)行部署和展示。

到此,將普通的網(wǎng)絡(luò)應(yīng)用轉(zhuǎn)成PWA的工作基本完成,我們部署到線上看下效果:

文件已被緩存用于離線訪問:

查詢一個郵編試試,可以發(fā)現(xiàn)請求被緩存了下來:

我們隨后關(guān)掉網(wǎng)絡(luò),再查詢剛剛的那個郵編,發(fā)現(xiàn)在網(wǎng)絡(luò)請求失敗之后立即切換用本地緩存的數(shù)據(jù):

好了,一個簡單的PWA就已經(jīng)制作完成了。當(dāng)然PWA的功能遠(yuǎn)不止此所展示的,依次按壓,安裝到手機(jī),后續(xù)有機(jī)會再跟大家分享,謝謝。

總結(jié)

以上是生活随笔為你收集整理的手把手教你制作一个PWA应用教程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。